標籤:key printf += perl return algo clu size tarjan
#include <vector>#include <cstdio>#include <cstring>#include <iostream>#include <algorithm>#define maxn 1005#define maxm 1000005using namespace std;struct Edge{ int u,v; Edge(int u=0,int v=0):u(u),v(v){}}e[maxm];int n,m,stamp,dfn[maxn],low[maxn],bccno[maxn],bcc_cnt;vector<int> vec[maxn];bool isbridge[maxm];void tarjan(int index,int fa){ int tmp; dfn[index]=low[index]=++stamp; for(int i=0;i<vec[index].size();i++) { tmp=e[vec[index][i]].v; if(!dfn[tmp]) { tarjan(tmp,index); low[index]=min(low[index],low[tmp]); if(low[tmp]>dfn[index]) isbridge[vec[index][i]]=isbridge[vec[index][i]^1]=1; } else if(dfn[tmp]<dfn[index] && tmp!=fa) { low[index]=min(low[index], dfn[tmp]); } }}void dfs(int index){ dfn[index]=1; bccno[index]=bcc_cnt; for(int i=0;i<vec[index].size();i++) { int tmp=vec[index][i]; if(isbridge[tmp]) continue; if(!dfn[e[tmp].v]) { dfs(e[tmp].v); } }}void find_ebcc(){ bcc_cnt=stamp=0; memset(dfn,0,sizeof(dfn)); memset(low,0,sizeof(low)); memset(bccno,0,sizeof(bccno)); memset(isbridge,0,sizeof(isbridge)); for(int i=1;i<=n;i++) if(!dfn[i]) tarjan(i, -1); memset(dfn,0,sizeof(dfn)); for(int i=1;i<=n;i++) { if(!dfn[i]) { bcc_cnt++; dfs(i); } } }int main(){ while(~scanf("%d %d",&n,&m)) { memset(vec,0,sizeof(vec)); int x,y; for(int i=0;i<m;i++) { scanf("%d %d",&x,&y); e[i*2]=Edge(x,y); vec[x].push_back(2*i); e[i*2+1]=Edge(y,x); vec[y].push_back(2*i+1); } find_ebcc(); if(bcc_cnt==1) printf("0\n"); else { memset(dfn,0,sizeof(dfn)); for(int i=0;i<m*2;i+=2) { x=e[i].u, y=e[i].v; if(bccno[x]!=bccno[y]) { dfn[bccno[x]]++; dfn[bccno[y]]++; } } int a=0,b=0; for(int i=1;i<=bcc_cnt;i++) { if(dfn[i]==0) a++; if(dfn[i]==1) b++; } printf("%d\n",a+(b+1)/2); } } return 0;}
邊雙聯通分量