Ant Trip(区别于二分匹配中最小路径覆盖的一笔画问题)

题目链接:

http://acm.hdu.edu.cn/showproblem.php?pid=3018

题目:

Problem Description
Ant Country consist of N towns.There are M roads connecting the towns.

Ant Tony,together with his friends,wants to go through every part of the country.

They intend to visit every road , and every road must be visited for exact one time.However,it may be a mission impossible for only one group of people.So they are trying to divide all the people into several groups,and each may start at different town.Now tony wants to know what is the least groups of ants that needs to form to achieve their goal.
 
Input
Input contains multiple cases.Test cases are separated by several blank lines. Each test case starts with two integer N(1<=N<=100000),M(0<=M<=200000),indicating that there are N towns and M roads in Ant Country.Followed by M lines,each line contains two integers a,b,(1<=a,b<=N) indicating that there is a road connecting town a and town b.No two roads will be the same,and there is no road connecting the same town.
 
Output
For each test case ,output the least groups that needs to form to achieve their goal.
 
Sample Input
3 3 1 2 2 3 1 3 4 2 1 2 3 4
 
Sample Output
1 2
Hint
New ~~~ Notice: if there are no road connecting one town ,tony may forget about the town. In sample 1,tony and his friends just form one group,they can start at either town 1,2,or 3. In sample 2,tony and his friends must form two group.
 
Source
 1 /*
 2 问题 给出n个顶点和m条边,n<=100000,m<=200000,若要遍历所有的边且每条边只能走一次,问至少需要几个起点
 3 保证没有重复道路,保证道路两端的城市是不同的,存在孤立的点,例如 3个点,1条边,1和2联通,那么3就是孤立的点
 4 
 5 解题思路 简单总结就是一笔画问题,画的时候,要么a--->b(一条线),即a和b均为奇点(度数为奇数的点),要么a--->a(一个圈),即该圈中没有奇点
 6 由于连通图中不可能存在奇数个奇点,换句话说连通图中奇点要么不出现,即存在欧拉回路,只需要一笔,要么成对出现,每一对需要一笔
 7 那么总的笔画数等于 所有奇点的个数除以2(孤立的点度数为0,为偶数) 加上 欧拉回路数
 8  
 9 输入时计算每个顶点的度数,使用并查集将图分成一块一块,遍历每一个顶点,找出奇点计数并且标记其根节点;再遍历顶点,
10 如果不是孤立的点 且 是根 且 该根没有被标记过,即为欧拉回路。  
11 */
12 #include<stdio.h>
13 #include<string.h>
14 int deg[200010],fat[100010],book[100010];
15 void merge(int a, int b);
16 int getf(int x);
17 
18 int main()
19 {
20     int n,m;
21     int i,a,b;
22     while(scanf("%d%d",&n,&m) != EOF)
23     {
24         memset(deg,0,sizeof(deg));
25         for(i=1;i<=n;i++){
26             fat[i]=i;
27         }
28         for(i=1;i<=m;i++){
29             scanf("%d%d",&a,&b);
30             deg[a]++;
31             deg[b]++;
32             merge(a,b);
33         }
34         
35         memset(book,0,sizeof(book)); 
36         int singsum=0;
37         for(i=1;i<=n;i++){
38             if(deg[i] & 1){
39                 book[ getf(i) ]=1;//标记以该点为根的一块图中存在奇点 
40                 singsum++;
41             }
42         }
43         
44         int eulenum=0;
45         for(i=1;i<=n;i++){
46             if(deg[i] > 0 && i==fat[i] && 0 == book[i])//不是孤立的点 且 是根 且 该根没有被标记过,即是欧拉回路 
47                 eulenum++;    
48         }
49         printf("%d
",singsum/2+eulenum);
50     }
51     return 0;
52 }
53 void merge(int a, int b)
54 {
55     int t1,t2;
56     t1=getf(a);
57     t2=getf(b);
58     if(t1 != t2){
59         fat[t2]=t1;
60     }    
61 } 
62 int getf(int x)
63 {
64     return fat[x]==x ? x : fat[x]=getf(fat[x]);
65 }
 
原文地址:https://www.cnblogs.com/wenzhixin/p/8488246.html