和求割点类似,只要把>=改成>即可。这里想解释一下的是,无向图没有重边,怎么可以使得low[v]=dfn[u]呢?只要它们之间再来一个点即可。
总感觉图论要很仔细地想啊- -一不小心就弄混了。。
另外从这题发现,代码还是写成模块化比较好,比如solve一个函数,init一个函数等等,这样可以避免很多东西忘记写,比方说dfn或者G的清空等等。。
代码如下:
1 #include <stdio.h> 2 #include <stack> 3 #include <algorithm> 4 #include <string.h> 5 #include <vector> 6 using namespace std; 7 8 const int N = 100+5; 9 10 stack<int> S; 11 int scc_cnt; 12 int dfs_clock; 13 int dfn[N]; 14 int low[N]; 15 int iscut[N]; 16 vector<int> G[N]; 17 int n; 18 19 struct bridge 20 { 21 int u,v; 22 void clear() 23 { 24 if(this->u > this->v) swap(this->u,this->v); 25 } 26 bool operator < (const bridge & A) const 27 { 28 return u==A.u ? v<A.v : u<A.u; 29 } 30 }; 31 vector<bridge> ans; 32 33 void dfs(int u,int fa) 34 { 35 dfn[u]=low[u]=++dfs_clock; 36 for(int i=0;i<G[u].size();i++) 37 { 38 int v = G[u][i]; 39 if(!dfn[v]) 40 { 41 dfs(v,u); 42 low[u]=min(low[u],low[v]); 43 if(low[v]>dfn[u]) 44 { 45 bridge bri = (bridge){u,v}; 46 bri.clear(); 47 ans.push_back(bri); 48 } 49 } 50 else if(dfn[v]<dfn[u] && v!=fa) 51 { 52 low[u]=min(low[u],dfn[v]); 53 } 54 } 55 } 56 57 void init() 58 { 59 for(int i=0;i<n;i++) G[i].clear(); 60 memset(dfn,0,sizeof(dfn)); 61 dfs_clock=0; 62 ans.clear(); 63 } 64 65 void solve() 66 { 67 for(int i=0;i<n;i++) 68 { 69 if(!dfn[i]) dfs(i,-1); 70 } 71 72 sort(ans.begin(),ans.end()); 73 printf("%d critical links\n",ans.size()); 74 for(int i=0;i<ans.size();i++) 75 { 76 printf("%d - %d\n",ans[i].u,ans[i].v); 77 } 78 puts(""); 79 } 80 81 int main() 82 { 83 while(scanf("%d",&n)==1) 84 { 85 init(); 86 87 for(int i=1;i<=n;i++) 88 { 89 int u,num; 90 scanf("%d (%d)",&u,&num); 91 92 while(num--) 93 { 94 int v; 95 scanf("%d",&v); 96 G[u].push_back(v); 97 G[v].push_back(u); 98 } 99 } 100 solve(); 101 } 102 return 0; 103 }
时间: 2024-10-10 10:23:29