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 }