HDU 3018 Ant Trip (欧拉回路)
Ant Trip
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 904 Accepted Submission(s): 338
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.
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
Recommend
gaojie
题意:每条边过且只过一次,问至少要画几笔才能全部边都经过。。孤立的点忽视。
分析:首先,你用笔来画的话,只可能有2种,一:每回路,a——>b 二:形成回路,a——>...——>a
对于图中的每一块,度数数为奇数的点必须是由第一种画出来的,所以奇数/2就是画的笔数
由两种结合而成的图,也只是奇数/2
特别的,如果图只有第二种的话,即该块中不存在奇数点,则只要画一笔
对于整副图(每一块块组合而成),等于 :第一块奇数点/2+第二块奇数点/2+.......,最后得,图的总奇数点/2
接着还要计算有多少块里不存在奇数点(不存在奇数点的那块中,一定没有第一种画法,只需要画一笔),累加起来就得到答案了。。
(如果是个欧拉回路一笔就可以完成,如果是个其它连通集,要根据这个集合的奇度数而定,笔划数=奇度数/2,用并查集来判断有多少个连通集,然后用vector来存这些连通集,通过判断度数是奇偶性来确定是否为欧拉回路;总之笔划数 = 奇度数/2 + 欧拉回路数;)
- /* 一笔画问题: 每条边过且只过一次,问至少要画几笔才能全部边都经过(不考虑鼓励的点)
- 图有多个集合构成 集合有两种
- 一种为含奇数点的 一种为只含偶数点的
- 对于含奇数点的 笔画数=奇数点个数/2
- 对于只含偶数点的 存在欧拉回路 笔画数=1
- 对于整张图 则 ans=总奇数点/2+只含偶数点的集合个数
- */
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; const int N=100010; int n,m; int father[N],deg[N],odd[N],vis[N]; vector<int> vt; void makeSet(){ for(int i=1;i<=n;i++) father[i]=i; } int findSet(int x){ if(x!=father[x]){ father[x]=findSet(father[x]); } return father[x]; } int main(){ //freopen("input.txt","r",stdin); while(~scanf("%d%d",&n,&m)){ vt.clear(); memset(vis,0,sizeof(vis)); memset(deg,0,sizeof(deg)); memset(odd,0,sizeof(odd)); makeSet(); int x,y; while(m--){ scanf("%d%d",&x,&y); deg[x]++; deg[y]++; int fx=findSet(x); int fy=findSet(y); if(fx!=fy) father[fx]=fy; } for(int i=1;i<=n;i++){ int fi=findSet(i); if(!vis[fi]){ vt.push_back(fi); //vt保存着集合,集合就是图 vis[fi]=1; } if(deg[i]%2==1) odd[fi]++; //保存这个集合的奇数度数的个数 } int ans=0; for(int i=0;i<(int)vt.size();i++){ int tmp=vt[i]; if(deg[tmp]==0) //孤立点 continue; if(odd[tmp]==0) //该集合是欧拉回路,有一条路 ans++; else ans+=odd[tmp]/2; } printf("%d\n",ans); } return 0; }