您的位置:首页 > 产品设计 > UI/UE

UVALive 4839 HDU 3686 Traffic Real Time Query System

2016-12-15 14:03 489 查看
题意:给出一幅图,询问从一条边到另一条有几个点必被经过

没看题解思路完全不对。。似乎知道了tarjan的新姿势

思路:首先按边跑tarjan。然后记录一下每条边在哪一个块中,记录一下割点;

然后建图:对于每个割点所在的块中(每个割点肯定在多个块中),建一个新点跟它们连边;

然后就是一棵树啦,当然到树剖啦。然后询问就是统计一条链上的割点有多少啦

(缩点基本是抄袭)

代码:

#include <bits/stdc++.h>
#define N 20009
#define M 200009
using namespace std;
int first
,number,x,y,n,m,dfn
,low
,sta[M];
int ebelong[M],subnet
,iscut
,Number,First[N<<1];
int top,cnt,taj,treecut[N<<1],vis[N<<1],Q,size[N<<1];
int num[N<<1],deep[N<<1],Top[N<<1],father[N<<1],Mson[N<<1];
vector<int> q
;
struct edge
{
int from,to,next,val,vis;
void add(int x,int y,int z)
{
from=x,to=y,next=first[x],first[x]=number,val=z,vis=0;
}
}e[M<<1];
struct Edge
{
int to,next;
void add(int x,int y)
{
to=y,next=First[x],First[x]=Number;
}
}E[N<<3];
void tarjan(int x)
{
dfn[x]=low[x]=++cnt;
for (int i=first[x];i;i=e[i].next)
if (!e[i].vis)
{
e[i].vis=e[i^1].vis=1;
sta[++top]=i;
if (!dfn[e[i].to])
{
tarjan(e[i].to);
low[x]=min(low[x],low[e[i].to]);
if (low[e[i].to]>=dfn[x])
{
++taj;
subnet[x]++;
iscut[x]=1;
int y,j;
do
{
j=sta[top--];
q[e[j].from].push_back(taj);
q[e[j].to].push_back(taj);
ebelong[e[j].val]=taj;
y=e[j].from;
}while (y!=x);
}
}
else low[x]=min(low[x],low[e[i].to]);
}
}
void dfs(int x)
{
vis[x]=1;
for (int i=First[x];i;i=E[i].next)
if (!vis[E[i].to])
{
num[E[i].to]=num[x];
if (treecut[x]) num[E[i].to]++;
dfs(E[i].to);
}
}
void dfs1(int x)
{
size[x]=1;
deep[x]=deep[father[x]]+1;
for (int i=First[x];i;i=E[i].next)
if (E[i].to!=father[x])
{
father[E[i].to]=x;
dfs1(E[i].to);
size[x]+=size[E[i].to];
if (size[E[i].to]>size[Mson[x]]) Mson[x]=E[i].to;
}
}
void dfs2(int x,int y)
{
Top[x]=y;
if (Mson[x]) dfs2(Mson[x],y);
for (int i=First[x];i;i=E[i].next)
if (E[i].to!=father[x]&&E[i].to!=Mson[x])
dfs2(E[i].to,E[i].to);
}
int lca(int x,int y)
{
for (;Top[x]!=Top[y];x=father[Top[x]])
if (deep[Top[x]]<deep[Top[y]]) swap(x,y);
return deep[x]<deep[y]?x:y;
}
int main()
{
while (scanf("%d%d",&n,&m),n&&m)
{
for (int i=1;i<=n;i++)
first[i]=dfn[i]=low[i]=iscut[i]=subnet[i]=0;
for (int i=1;i<=n;i++) q[i].clear();
number=1,top=cnt=taj=Number=0;
for (int i=1;i<=m;i++)
{
scanf("%d%d",&x,&y);
ebelong[i]=0;
e[++number].add(x,y,i);
e[++number].add(y,x,i);
}
for (int i=1;i<=n;i++)
if (!dfn[i])
{
tarjan(i);
subnet[i]--;
if (subnet[i]<=0) iscut[i]=0;
}
for (int i=1;i<=taj+n;i++) First[i]=treecut[i]=0;
for (int i=1;i<=n;i++)
if (iscut[i])
{
sort(q[i].begin(),q[i].end());
treecut[++taj]=1;
E[++Number].add(taj,q[i][0]);
E[++Number].add(q[i][0],taj);
for (int j=1;j<q[i].size();j++)
if (q[i][j-1]!=q[i][j])
{
E[++Number].add(taj,q[i][j]);
E[++Number].add(q[i][j],taj);
}
}
for (int i=1;i<=taj;i++)
Mson[i]=deep[i]=num[i]=father[i]=Top[i]=vis[i]=size[i]=0;
for (int i=1;i<=taj;i++)
if (!vis[i]) dfs(i),dfs1(i),dfs2(i,i);
scanf("%d",&Q);
for (int i=1;i<=Q;i++)
{
scanf("%d%d",&x,&y);
x=ebelong[x],y=ebelong[y];
if (!x||!y) puts("0");
else
{
int z=lca(x,y);
printf("%d\n",num[x]+num[y]-2*num[z]-treecut[z]);
}
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: