您的位置:首页 > 其它

hdu 3018 Ant Trip(一笔画问题)

2013-09-14 23:41 459 查看


AntTrip

TimeLimit:2000/1000MS(Java/Others)MemoryLimit:32768/32768K(Java/Others)

TotalSubmission(s):1169AcceptedSubmission(s):428



ProblemDescription

AntCountryconsistofNtowns.ThereareMroadsconnectingthetowns.

AntTony,togetherwithhisfriends,wantstogothrougheverypartofthecountry.

Theyintendtovisiteveryroad,andeveryroadmustbevisitedforexactonetime.However,itmaybeamissionimpossibleforonlyonegroupofpeople.Sotheyaretryingtodivideallthepeopleintoseveralgroups,andeachmaystartatdifferenttown.Now
tonywantstoknowwhatistheleastgroupsofantsthatneedstoformtoachievetheirgoal.



Input

Inputcontainsmultiplecases.Testcasesareseparatedbyseveralblanklines.EachtestcasestartswithtwointegerN(1<=N<=100000),M(0<=M<=200000),indicatingthatthereareNtownsandMroadsinAntCountry.FollowedbyMlines,eachlinecontainstwointegers
a,b,(1<=a,b<=N)indicatingthatthereisaroadconnectingtownaandtownb.Notworoadswillbethesame,andthereisnoroadconnectingthesametown.

Output

Foreachtestcase,outputtheleastgroupsthatneedstoformtoachievetheirgoal.

SampleInput

33
12
23
13

42
12
34


SampleOutput

1
2

Hint

New~~~Notice:iftherearenoroadconnectingonetown,tonymayforgetaboutthetown.
Insample1,tonyandhisfriendsjustformonegroup,theycanstartateithertown1,2,or3.
Insample2,tonyandhisfriendsmustformtwogroup.
题意:给出一个无向图,问最少画多少笔可以遍历图中所有边恰好一次。
思路:一笔画问题。我们知道,如果一个图是欧拉图,那么只需要画一笔。首先求出这个图有多少个连通块,然后求出每个连通块需要画多少笔,最后每个连通块需要画的笔数加起来即为答案。对于每个连通块,若所有点的度数都为偶数,则是欧拉图,只需画一笔;否则,需要画的笔数为奇度数点的数目/2.
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<map>
#include<cstdlib>
#defineL(rt)(rt<<1)
#defineR(rt)(rt<<1|1)
#definelllonglong
#defineeps1e-6
usingnamespacestd;

constintmaxn=100005;
intfa[maxn],d[maxn];
intcnt[maxn];
intn,m;
voidinit()
{
for(inti=1;i<=n;i++)fa[i]=i;
memset(d,0,sizeof(d));
memset(cnt,0,sizeof(cnt));
}
intfind_set(intx)
{
returnx==fa[x]?x:fa[x]=find_set(fa[x]);
}
voidUnion(inta,intb)
{
intra=find_set(a);
intrb=find_set(b);
if(ra==rb)return;
fa[ra]=rb;
}
intmain()
{
inta,b;
while(~scanf("%d%d",&n,&m))
{
init();
while(m--)
{
scanf("%d%d",&a,&b);
Union(a,b);
d[a]++;
d[b]++;
}
for(inti=1;i<=n;i++)
if(d[i]&1)cnt[find_set(i)]++;
intans=0;
for(inti=1;i<=n;i++)
if(fa[i]==i&&d[i])
{
if(!cnt[i])ans++;
elseans+=cnt[i]/2;
}
printf("%d\n",ans);
}
return0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: