1 /******************************************** 2 Network(POJ 3694) 3 http://poj.org/problem?id=3694 4 桥入门题 + LCA(树中最小公共祖先) 5 做这题必须要会用邻接表(做这题才学会),因为 6 给的边有重边,用vector不好记录重边。 7 8 ********************************************/ 9 10 #include<iostream> 11 #include<algorithm> 12 #include<cstring> 13 #include<cstdio> 14 using namespace std; 15 16 const int M=100005; 17 18 struct Eage ///邻接表建图 19 { 20 int v; 21 int next; 22 int vs; 23 }; 24 25 Eage eage[M*4]; 26 int low[M],dfn[M],father[M]; ///father[i]为i的父亲节点 27 int flag[M],vs[M],head[M]; ///falg[i]为i和i的父亲节点的边 28 int dfs_cut,ans,k; 29 30 void Init() 31 { 32 memset(dfn,0,sizeof(dfn)); 33 memset(low,0,sizeof(low)); 34 memset(flag,0,sizeof(flag)); 35 memset(vs,0,sizeof(vs)); 36 memset(head,-1,sizeof(head)); 37 dfs_cut=ans=k=0; 38 } 39 40 void add(int u,int v) 41 { 42 eage[k].v=v; 43 eage[k].vs=0; 44 eage[k].next=head[u]; 45 head[u]=k++; 46 } 47 48 void dfs(int u) ///求桥 49 { 50 vs[u]=1; 51 dfn[u]=low[u]=++dfs_cut; 52 for (int i=head[u];i!=-1;i=eage[i].next) 53 { 54 if (!eage[i].vs) 55 { 56 eage[i].vs=eage[i^1].vs=1; 57 int v=eage[i].v; 58 if (!vs[v]) 59 { 60 father[v]=u; 61 dfs(v); 62 low[u]=min(low[u],low[v]); 63 if (dfn[u]<low[v]) 64 { 65 ans++; 66 flag[v]=1; 67 } 68 } 69 else low[u]=min(low[u],dfn[v]); 70 } 71 } 72 } 73 74 void Lca(int u,int v) 75 { 76 if (dfn[u]<dfn[v]) 77 { 78 u^=v; 79 v^=u; 80 u^=v; 81 } 82 while (dfn[u]>dfn[v]) 83 { 84 if (flag[u]) ans--; 85 flag[u]=0; 86 u=father[u]; 87 } 88 while (u!=v) 89 { 90 if (flag[v]) ans--; 91 if (flag[u]) ans--; 92 flag[u]=0; 93 flag[v]=0; 94 v=father[v]; 95 u=father[u]; 96 } 97 } 98 99 int main() 100 { 101 // freopen("C://Users//Administrator//Desktop//in.txt","r",stdin); 102 // freopen("C://Users//Administrator//Desktop//out.txt","w",stdout); 103 int n,m,cut=0; 104 while (cin>>n>>m) 105 { 106 if (!n&&!m) return 0; 107 Init(); 108 for (int i=1;i<=n;i++) father[i]=i; 109 int u,v; 110 while (m--) 111 { 112 cin>>u>>v; 113 add(u,v); 114 add(v,u); 115 } 116 dfs(1); 117 cout<<"Case "<<++cut<<":"<<endl; 118 int q; 119 cin>>q; 120 while (q--) 121 { 122 cin>>u>>v; 123 Lca(u,v); 124 cout<<ans<<endl; 125 } 126 cout<<endl; 127 } 128 return 0; 129 }
时间: 2024-10-14 20:37:57