Ant Trip HDU - 3018

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.


        
 

题意概括:在一个地方由n个城镇,由m条路连接起来,现在有一波蚂蚁想把每个地方都走一边且每条路只能走一次,单独存在的城镇可以忽略,问最少需要把这一大波蚂蚁分成几小波?

解题思路:题中给出的点和边构成各种路,可以把路分为欧拉回路,如果是欧拉回路那么只需要一小波蚂蚁就可以在每条边都只经过一次的情况下走完所有的点,反之需要找出路上有多少个奇点,需要奇点数/2波蚂蚁才能完成人物。欧拉回路的判断需要用并查集,计算出每个点所在的路多少个点,大于1代表构成了路,反之单独的城镇忽略;在构成路的情况下在判断是否是欧拉回路,欧拉回路上不存在奇点。

代码:

#include<stdio.h>
#include<string.h>
#define N 100100
struct road
{
	int u,v;
}e[N*2];
int n,m,f[N],b[N], num[N],odd[N];;
int getf(int u)
{
	if(f[u]==u)
	{
		return u;
	}
	else
	{
		f[u]=getf(f[u]);
		return f[u];
	}
}
void merge(int u,int v)
{
	int t1=getf(u);
	int t2=getf(v);
	if(t1!=t2)
	{	
		f[t2]=t1;	
		return;
	}
	return ;
}
int main()
{
	int i,j;
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		for(i=0;i<m;i++)
		{
			scanf("%d %d",&e[i].u,&e[i].v);
		}
		//memset(a,0,sizeof(a));
		for(i=1;i<=n;i++)
		{
			f[i]=i;
		}
		memset(b,0,sizeof(b));
		for(i=0;i<m;i++)
		{
			merge(e[i].u,e[i].v);
			b[e[i].u]++;//计算每个点的入度、出度一共多少
			b[e[i].v]++;
		}
		
		memset(odd,0,sizeof(odd));
		memset(num,0,sizeof(num));
		for(i=1;i<=n;i++)
		{
			num[getf(i)]++;//计算每个点有多少个“子孙”
			if(b[i]%2==1)
			odd[getf(i)]++; //计算每条路上有几个奇点
		}
		int l=0;
		for(i=1;i<=n;i++)
		{
			//printf("%d   %d\n",num[i],odd[i]);
			if(num[i]>1&&odd[i]==0)//可以构成欧拉回路
			{
				l++;
			}
			else if(num[i]>1&&odd[i]>1)
			{
				l+=odd[i]/2;
			}
		}
		printf("%d\n",l);
	}
	return 0;	
} 
/*
5 4
1 2
2 3
1 3
4 5

5 4
1 2
2 3
1 3
4 3

*/

猜你喜欢

转载自blog.csdn.net/gakki_wpt/article/details/79475305