hdu 3018 Ant Trip

来源:互联网 发布:linux php7环境搭建 编辑:程序博客网 时间:2024/06/06 13:12


题目链接点击打开链接

Ant Trip

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 3295    Accepted Submission(s): 1311


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 31 22 31 34 21 23 4
 

Sample Output
12
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
2009 Multi-University Training Contest 12 - Host by FZU
 

Recommend
gaojie   |   We have carefully selected several similar problems for you:  3013 3015 3016 3011 3010 


题意:每条边过且只过一次,问至少要画几笔才能全部边都经过。。孤立的点忽视。

这道题是欧拉回路问题,考虑这道题,我们要先将图中的点分为不同的集合,即有边相连的点为一个集合,这个就要用并查集。对于每一个集合,如果集合中的每个点的度都是

偶数,那么说明这个图是欧拉图,一笔即可:如果集合有两个点的度是奇数,那么就是半欧拉图,一笔即可。

这个时候我们来证明一个问题,就是度为奇数的点一点有偶数个:我们知道每一条边都会产生两个度,因此总度数一定是奇数个,那么如果度数为奇数点的总个数如果为奇数个,那么总度数就为奇数,这就产生了矛盾,因此得证。

那么如果度数为奇数的点的数量大于2时,每两个度为奇数的边都需要另外再加一笔,于是我们发现半欧拉图也符合这个规律。

因此我们可以的到这个公式:

总之笔划数 = 奇度数%2 + 欧拉回路数。

AC代码:

#include<iostream>#include<stdio.h>using namespace std;int m,n;int a,b;int father[100010];int c[100010];bool check[100010];int du[100010];int ji[100010];int ans;int cnt;int find(int x){    if(x!=father[x])        father[x]=find(father[x]);        return father[x];}void join(int x,int y){    int xx=find(x);    int yy=find(y);    if(xx!=yy)        father[xx]=yy;}int main(){    while(~scanf("%d%d",&n,&m))    {        for(int i=1;i<=n;i++)        {            father[i]=i;            du[i]=0;            check[i]=false;            ji[i]=0;        }        ans=0;        cnt=0;        for(int i=1;i<=m;i++)        {            scanf("%d%d",&a,&b);            du[a]++;            du[b]++;            join(a,b);        }        for(int i=1;i<=n;i++)        {            int ii=find(i);            if(!check[ii])            {                check[ii]=true;                c[++cnt]=ii;            }            if(du[i]%2!=0)                ji[ii]++;        }        for(int i=1;i<=cnt;i++)        {            int temp=c[i];            if(du[temp]==0)                continue;            if(ji[temp]==0)                ans++;            else                ans=ans+ji[temp]/2;        }        printf("%d\n",ans);    }    return 0;}



原创粉丝点击