https://vjudge.net/problem/HDU-3686

点双啊,就是在求割顶的时候,另外用一个栈来存一些

在遍历u点出发的边时,遇到树边或反向边(u,v)就把此边加入栈(可能要记一下边的编号)(但是,如果(u,v)是反过来看的反向边(此时dfn[v]>=dfn[u];实际反向边应该为(v,u))或者反过来的树边(此时k==(last^1))就不能加入)

遇到一个割点,就多一个点双(不考虑因为(fa<0&&child==1)的特判而去掉的割点)

计算(u,v)中遇到割点后,就不断从栈顶弹出边,直到栈顶的边与(u,v)相等,然后再弹出一个边;所有这些弹出的边以及边的两个端点都属于这个点双

先对原图求点双连通分量,求出每条边属于的点双

然后为原图中每一个点双新建一个点,向这个点双内每一个点连边,去掉原图所有边,得到一个新图(实际上是一棵树)

询问两条边a,b时,先找出它们属于的点双对应的点编号x,y,那么答案就是新树上x与y的最短路径中"非点双对应的点"的数量(由于实际是要求这两个点双在原图中的路径间割点数量,而只有割点才可能成为新树中要统计的点)

https://blog.csdn.net/u013480600/article/details/44835827

错误记录:

倍增写错。。。115行少d[anc[x][0]][0]

 #include<cstdio>
#include<algorithm>
#include<cstring>
#include<vector>
using namespace std;
#define fi first
#define se second
#define mp make_pair
#define pb push_back
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define CLR(x) memset(x,0,sizeof(x))
#define N 10100
#define M 101000
typedef pair<pii,int> ppi;
struct E{int to,nxt;};
namespace G
{
E e[M<<];
int f1[N],ne;
int dfn[N],bno[N],dfc,cnt,bn2[M];bool iscut[N];
ppi st[M];int top;
vector<int> bcc[N];
//#define D(x) ((x)&2147483646)
void clr()
{
CLR(f1);ne=;
CLR(dfn);CLR(bno);CLR(iscut);CLR(bn2);dfc=cnt=top=;
}
void me(int a,int b)
{
e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
}
int dfs(int u,int last)
{
int k,v,lowu=dfn[u]=++dfc,chi=,lowv;ppi x;
for(k=f1[u];k;k=e[k].nxt)
{
v=e[k].to;
if(!dfn[v])
{
st[++top]=mp(mp(u,v),k);chi++;
lowv=dfs(v,k);lowu=min(lowu,lowv);
if(lowv>=dfn[u])
{
iscut[u]=;
cnt++;bcc[cnt].clear();
for(;;)
{
x=st[top--];
if(bno[x.fi.fi]!=cnt)
bno[x.fi.fi]=cnt,bcc[cnt].pb(x.fi.fi);
if(bno[x.fi.se]!=cnt)
bno[x.fi.se]=cnt,bcc[cnt].pb(x.fi.se);
bn2[x.se/]=cnt;
if(x.fi.fi==u&&x.fi.se==v) break;
}
}
}
else if(dfn[v]<dfn[u]&&k!=(last^))
{
st[++top]=mp(mp(u,v),k);
lowu=min(lowu,dfn[v]);
}
}
if(last<&&chi==) iscut[u]=;
return lowu;
}
}
int n,m,l2n=,qq;
namespace T
{
E e[N<<];
int f1[N<<],ne;
int anc[N<<][],d[N<<][],dep[N<<];
//d[i][j]表示i点到其2^j级祖先中(含i,不含祖先),共有几个圆点
bool vis[N<<];
void clr() {CLR(f1);CLR(anc);CLR(vis);CLR(d);CLR(dep);ne=;}
void me(int a,int b)
{
e[++ne].to=b;e[ne].nxt=f1[a];f1[a]=ne;
e[++ne].to=a;e[ne].nxt=f1[b];f1[b]=ne;
}
void dfs(int u,int fa)
{
int i;
vis[u]=;anc[u][]=fa;d[u][]=(u<=n);
for(i=;i<=l2n;i++)
{
anc[u][i]=anc[anc[u][i-]][i-];
d[u][i]=d[u][i-]+d[anc[u][i-]][i-];
}
for(int k=f1[u];k;k=e[k].nxt)
if(e[k].to!=fa)
{
dep[e[k].to]=dep[u]+;
dfs(e[k].to,u);
}
}
int ask(int x,int y)
{
int t,i,ans=;
if(dep[x]<dep[y]) swap(x,y);
for(t=dep[x]-dep[y],i=;t>;t>>=,i++)
if(t&) ans+=d[x][i],x=anc[x][i];
if(x==y) return ans;
for(i=l2n;i>=;i--)
if(anc[x][i]!=anc[y][i])
{
ans+=(d[x][i]+d[y][i]);
x=anc[x][i];y=anc[y][i];
}
ans+=(d[x][]+d[y][]+d[anc[x][]][]);
return ans;
}
}
int main()
{
int a,b,i,j;
while()
{
G::clr();T::clr();
scanf("%d%d",&n,&m);
if(n==&&m==) break;
for(i=;i<=m;i++) scanf("%d%d",&a,&b),G::me(a,b);
for(i=;i<=n;i++) if(!G::dfn[i]) G::dfs(i,-);
for(i=;i<=G::cnt;i++)
for(j=;j<G::bcc[i].size();j++)
T::me(n+i,G::bcc[i][j]);
for(i=;i<=n+G::cnt;i++)
if(!T::vis[i])
T::dfs(i,);
scanf("%d",&qq);
while(qq--)
{
scanf("%d%d",&a,&b);
printf("%d\n",T::ask(n+G::bn2[a],n+G::bn2[b]));
}
}
return ;
}

Traffic Real Time Query System HDU - 3686的更多相关文章

  1. HDU 3686 Traffic Real Time Query System (图论)

    HDU 3686 Traffic Real Time Query System 题目大意 给一个N个点M条边的无向图,然后有Q个询问X,Y,问第X边到第Y边必需要经过的点有多少个. solution ...

  2. CH#24C 逃不掉的路 和 HDU3686 Traffic Real Time Query System

    逃不掉的路 CH Round #24 - 三体杯 Round #1 题目描述 现代社会,路是必不可少的.任意两个城镇都有路相连,而且往往不止一条.但有些路连年被各种XXOO,走着很不爽.按理说条条大路 ...

  3. HDU 3686 Traffic Real Time Query System(双连通分量缩点+LCA)(2010 Asia Hangzhou Regional Contest)

    Problem Description City C is really a nightmare of all drivers for its traffic jams. To solve the t ...

  4. HDU3686 Traffic Real Time Query System 题解

    题目 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, t ...

  5. Traffic Real Time Query System 圆方树+LCA

    题目描述 City C is really a nightmare of all drivers for its traffic jams. To solve the traffic problem, ...

  6. hdu 3686 Traffic Real Time Query System 点双两通分量 + LCA。这题有重边!!!

    http://acm.hdu.edu.cn/showproblem.php?pid=3686 我要把这题记录下来. 一直wa. 自己生成数据都是AC的.现在还是wa.留坑. 我感觉我现在倒下去床上就能 ...

  7. HDU 3686 Traffic Real Time Query System(点双连通)

    题意 ​ 给定一张 \(n\) 个点 \(m\) 条边的无向图,\(q\) 次询问,每次询问两边之间的必经之点个数. 思路 ​ 求两点之间必经之边的个数用的是边双缩点,再求树上距离.而对比边双和点双之 ...

  8. HDU Traffic Real Time Query System

    题目大意是:对于(n, m)的图,给定边a, b查询从a到b要经过的割点的最少数目. 先tarjan算法求双连通然后缩点,即对于每个割点将周围的每个双连通看成一个点与之相连.然后求解LCA即可,距离d ...

  9. 【HDOJ】3686 Traffic Real Time Query System

    这题做了几个小时,基本思路肯定是求两点路径中的割点数目,思路是tarjan缩点,然后以割点和连通块作为新节点见图.转化为lca求解.结合点——双连通分量与LCA. /* 3686 */ #includ ...

随机推荐

  1. VC++ 学习笔记(四):停止还是暂停这个系列

    我已经很久没有更新这个话题了,原因是多方面的,比如比较忙,比如我参与的项目不使用C++.最近因为需要在C#的客户端中调用第三方的C++API,又想起了这个话题.在跟公司里的C++方面专家聊过之后,我有 ...

  2. 【php】读取&quot;文件列表&quot;按时间倒序显示,并递归显示各层文件夹、!

    思路: 1.读取该php所在文件夹的文件列表,用"改动时间.文件名称"做键值对,塞入数组.对"改动时间"倒序.(貌似不能直接按时间倒序读取文件列表,此处为间接方 ...

  3. sendmessage传递数组

    1.在初始化数组尤其是需要每次都初始化的时候,很多同学使用循环来进行,这样不但速度慢,而且写起来也很长.所以现在提供一个函数来实现这个功能... 原型:extern void *memset(void ...

  4. Drupal 7模板(主题钩子)的建议

    这一块的内容很多其它的讲的是样例.所以这里请直接稳步官方站点查看吧.链接 https://drupal.org/node/1089656

  5. base64 hash sha

    /*! * Crypto-JS v1.1.0 * http://code.google.com/p/crypto-js/ * Copyright (c) 2009, Jeff Mott. All ri ...

  6. MRP-MD04 中的函数

    1.需求溯源 : MD_PEGGING_NODIALOG 2.实时库存 : MD_STOCK_REQUIREMENTS_LIST_API 这个函数中MDPSX 和 MDEZX 是通过 MDPS 的 I ...

  7. Safair css hack

    一下方式不会影响chrome浏览器样式 _::-webkit-full-page-media, _:future, :root .class{ /*此处放css样式*/ }

  8. IE兼容模式

    何为兼容模式 这个和IE的发展历程相关,在IE8之前Browser基本上属于IE一家独大,然后ie就有很多与web standard不一致的地方,比如只有自己才看得懂的tag等.后来由于chrome, ...

  9. Silverlight中使用MVVM(4)

    Silverlight中使用MVVM(1)--基础 Silverlight中使用MVVM(2)—提高 Silverlight中使用MVVM(3)—进阶 Silverlight中使用MVVM(4)—演练 ...

  10. Binder通信机制介绍

    1.Binder通信机制介绍 这篇文章会先对比Binder机制与Linux的通信机制的差别,了解为什么Android会另起炉灶,采用Binder.接着,会根据 Binder的机制,去理解什么是Serv ...