1. 程式人生 > >BZOJ1718 [Usaco2006 Jan] Redundant Paths 分離的路徑

BZOJ1718 [Usaco2006 Jan] Redundant Paths 分離的路徑

++ 配對 body pac include style zoj urn else

求邊雙聯通分量,然後組成一顆樹,葉子結點兩兩配對即可。

技術分享圖片

By:大奕哥

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=100005;
 4 int head[N],low[N],fa[200050],p,dfn[N],in[N],s[N],top,idx,cnt,num,col[N],du[N],ans,n,m;
 5 struct node{
 6     int f,to,nex;
 7 }e[200050];
 8 void add(int x,int y)
 9 {
10     e[++cnt].to=y;e[cnt].f=x;e[cnt].nex=head[x];head[x]=cnt;
11 } 12 void tarjan(int x,int f) 13 { 14 dfn[x]=low[x]=++idx;s[++top]=x;in[x]=1; 15 for(int i=head[x];i;i=e[i].nex) 16 { 17 int y=e[i].to; 18 if(fa[i]==f)continue; 19 if(!dfn[y]) 20 { 21 tarjan(y,fa[i]); 22 low[x]=min(low[x],low[y]);
23 } 24 else if(in[y]) 25 low[x]=min(dfn[y],low[x]);//in數組無向圖不必加,有向圖必加。 26 } 27 if(low[x]==dfn[x]) 28 { 29 num++;int a=-1; 30 do{ 31 a=s[top--]; 32 in[a]=0; 33 col[a]=num; 34 }while(a!=x); 35 }
36 } 37 int main() 38 { 39 scanf("%d%d",&n,&m); 40 for(int i=1;i<=m;++i) 41 { 42 int x,y; 43 scanf("%d%d",&x,&y); 44 add(x,y);fa[cnt]=++p; 45 add(y,x);fa[cnt]=p; 46 } 47 for(int i=1;i<=n;++i) 48 if(!dfn[i]){ 49 tarjan(i,0); 50 } 51 for(int i=1;i<=cnt;++i) 52 { 53 int x=e[i].f;int y=e[i].to; 54 if(col[x]==col[y])continue; 55 du[col[x]]++;du[col[y]]++; 56 } 57 for(int i=1;i<=num;++i) 58 if(du[i]==2)ans++; 59 printf("%d\n",ans+1>>1); 60 return 0; 61 }

BZOJ1718 [Usaco2006 Jan] Redundant Paths 分離的路徑