欧拉回路(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 }