hdu2460 tarjan无向图边双连通分量(桥)+lca

题意需要求出每加一条边求出桥的数目,因为询问数不多,所以可以在tarjan预处理之后在每个询问后面暴力查询lca=

和有向图强连通分量差不多,反正都是tarjan搞的TUT

hdu又需要手动扩栈==

 1 #pragma comment(linker,"/STACk:10240000,10240000")
 2 #include<stdio.h>
 3 #include<string.h>
 4 #include<algorithm>
 5 using namespace std;
 6 int now,Head[400005],Next[400005],Point[400005];
 7 int pre[400005],low_link[400005],dfs_clock,father[400005];
 8 int ans,bridge[400005];
 9 void add(int u,int v)
10 {
11   Next[++now]=Head[u];
12   Head[u]=now;
13   Point[now]=v;
14 }
15 void dfs(int u,int fa)
16 {
17   int i,v,flag=0;
18   pre[u]=low_link[u]=++dfs_clock;
19   for (i=Head[u];i;i=Next[i]){
20     v=Point[i];
21     if (v==fa&&flag==0) {flag=1; continue; }
22     if (!pre[v]){
23       father[v]=u;
24       dfs(v,u);
25       low_link[u]=min(low_link[u],low_link[v]);
26       if (low_link[v]>pre[u]){ 
27         bridge[v]=1;
28         ans++;
29       }
30     }
31     else low_link[u]=min(low_link[u],pre[v]);
32   }
33 }
34 void lca(int u,int v)
35 {
36   if (pre[u]>pre[v]) swap(u,v);
37   while (pre[v]>pre[u]){
38     if (bridge[v]){
39       ans--;
40       bridge[v]=0;
41     }
42     v=father[v];
43   }
44   while (u!=v){
45     if (bridge[u]) { bridge[u]=0; ans--; }
46     if (bridge[v]) { bridge[v]=0; ans--; }
47     u=father[u]; v=father[v];
48   }
49 }
50 int main()
51 {
52   int n,m,x,y,q,i,t=0;
53   while (~scanf("%d%d",&n,&m)&&(n||m))
54   {
55     memset(Head,0,sizeof(Head));
56     now=dfs_clock=ans=0;
57     while (m--){
58       scanf("%d%d",&x,&y);
59       add(x,y); add(y,x);
60     }
61     memset(bridge,0,sizeof(bridge));
62     memset(pre,0,sizeof(pre));
63     for (i=1;i<=n;i++) father[i]=i;
64     dfs(1,0);
65     printf("Case %d:\n",++t);
66     scanf("%d",&q);
67     while (q--){
68       scanf("%d%d",&x,&y);
69       lca(x,y);
70       printf("%d\n",ans);
71     }
72     printf("\n");
73   }
74   return 0;
75 }
View Code

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2460

posted on 2015-04-01 18:56  xiao_xin  阅读(143)  评论(0编辑  收藏  举报

导航