欧拉回路(hdu3018)
刚学图论不久,看着别人的博客慢慢学了一点基础的,感觉还是有点力不从心,感觉图论的题好多长得都很像,什么太监算法(Tarjan),Kosaraju,当然最基础的还是并查集。。。好了继续介绍这道题。。。。
题意:蚂蚁王国有n个城市(n个点),要求输入的是第a个城市可以到第b个城市(m个边),求最少画几笔覆盖全部边。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 #define m 100002 6 int point[m];///每个强连通分量的端点 7 int cnt;///计数 8 int fa[m];///并查集的父亲节点 9 int qiang[m];///强连通分量 10 bool used[m];///记录有没有访问过 11 int du[m];///度,如果是偶数的话+1,如果是奇数的话+=点数*1/2; 12 void unit(int n) 13 { 14 cnt=0; 15 for(int i=0;i<=n;i++) 16 { 17 point[i] = 0; 18 qiang[i] = 0; 19 fa[i]=-1; 20 used[i]=0; 21 } 22 } 23 int find(int x) 24 { 25 if(fa[x] >= 0) 26 { 27 fa[x]=find(fa[x]); 28 return fa[x]; 29 } 30 return x; 31 } 32 void Union(int a,int b) 33 { 34 int x1 = find(a); 35 int x2 = find(b); 36 if(x1 == x2) 37 return ; 38 int r1 = fa[x1]; 39 int r2 = fa[x2]; 40 if(r1 < r2) 41 { 42 fa[x2] = x1; 43 fa[x1] += r2; 44 } 45 else 46 { 47 fa[x1]=x2; 48 fa[x2] += r1; 49 } 50 } 51 int main() 52 { 53 int n=0,t=0; 54 int x=0,y=0; 55 while(~scanf("%d%d",&n,&t)) 56 { 57 unit(n); 58 cnt=0; 59 for(int i=1;i <= t;i++) 60 { 61 scanf("%d%d", &x , &y); 62 63 du[x]++; 64 du[y]++; 65 Union(x , y); 66 } 67 68 for(int i=1;i<=n;i++) 69 { 70 int f = find(i); 71 if( !used[f] ) 72 { 73 used[f] = 1; 74 qiang[cnt++] = f; 75 } 76 if(du[i]%2 == 1) 77 point[f]++; 78 } 79 int output=0; 80 for(int i=0;i < cnt;i++) 81 { 82 if(du[qiang[i]] == 0) 83 continue; 84 if(point[qiang[i]]==0) 85 output++; 86 else 87 { 88 output += point[qiang[i]]/2; 89 } 90 } 91 printf("%d\n", output); 92 } 93 }