1 #include<cstdio> 2 #include<cstring> 3 #include<stack> 4 #include<vector> 5 #include<algorithm> 6 using namespace std; 7 8 struct Edge 9 { 10 int u,v; 11 }; 12 13 const int N=10005; 14 vector<int>block[N]; 15 vector<int>G[N]; 16 stack<Edge>sk; 17 int dfn[N],bccno[N]; 18 int n,m,dfs_clock,bcc_cnt,ans1,ans2,sum; 19 bool vis[N]; 20 21 void init() 22 { 23 memset(bccno,0,sizeof(bccno)); 24 memset(dfn,0,sizeof(dfn)); 25 for(int i=0;i<n;i++) 26 G[i].clear(); 27 ans1=ans2=dfs_clock=bcc_cnt=0; 28 } 29 30 int tarjan(int u,int fa) 31 { 32 int lowu=dfn[u]=++dfs_clock; 33 int child=0; 34 for(int i=0;i<G[u].size();i++) 35 { 36 int v=G[u][i]; 37 Edge e=(Edge){u,v}; 38 if(!dfn[v]) 39 { 40 sk.push(e); 41 child++; 42 int lowv=tarjan(v,u); 43 lowu=min(lowu,lowv); 44 if(lowv>=dfn[u]) 45 { 46 if(lowv>dfn[u]) 47 ans1++; 48 bcc_cnt++; 49 block[bcc_cnt].clear(); 50 while(1) 51 { 52 Edge x=sk.top(); 53 sk.pop(); 54 if(bccno[x.u]!=bcc_cnt) 55 { 56 block[bcc_cnt].push_back(x.u); 57 bccno[x.u]=bcc_cnt; 58 } 59 if(bccno[x.v]!=bcc_cnt) 60 { 61 block[bcc_cnt].push_back(x.v); 62 bccno[x.v]=bcc_cnt; 63 } 64 if(x.u==u&&x.v==v)break; 65 } 66 int sum=0; 67 memset(vis,0,sizeof(vis)); 68 for(int i=0;i<block[bcc_cnt].size();i++) 69 vis[block[bcc_cnt][i]]=1; 70 for(int i=0;i<block[bcc_cnt].size();i++) 71 { 72 int u=block[bcc_cnt][i]; 73 for(int j=0;j<G[u].size();j++) 74 if(vis[G[u][j]]) 75 sum++; 76 } 77 sum/=2; 78 if(sum>block[bcc_cnt].size()) 79 ans2+=sum; 80 } 81 } 82 else if(dfn[v]<dfn[u]&&v!=fa) 83 { 84 sk.push(e); 85 lowu=min(lowu,dfn[v]); 86 } 87 } 88 return lowu; 89 } 90 91 int main() 92 { 93 while(scanf("%d%d",&n,&m),n|m) 94 { 95 init(); 96 for(int i=0;i<m;i++) 97 { 98 int u,v; 99 scanf("%d%d",&u,&v); 100 G[u].push_back(v); 101 G[v].push_back(u); 102 } 103 for(int i=0;i<n;i++) 104 { 105 if(!dfn[i]) 106 tarjan(i,-1); 107 } 108 printf("%d %d\n",ans1,ans2); 109 } 110 return 0; 111 }
原文:http://www.cnblogs.com/homura/p/4836603.html