【hdu4018】Ant Trip 欧拉图

Ant Trip

TimeLimit: 2000/1000 MS (Java/Others)    Memory Limit:32768/32768 K (Java/Others)
Total Submission(s): 3433    Accepted Submission(s): 1362

ProblemDescription

Ant Country consist of N towns.There areM roads connecting the towns.

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

They intend to visit every road , and every road must be visited for exact onetime.However,it may be a mission impossible for only one group of people.Sothey are trying to divide all the people into several groups,and each may startat different town.Now tony wants to know what is the least groups of ants thatneeds to form to achieve their goal.

 

 

Input

Input contains multiple cases.Test casesare separated by several blank lines. Each test case starts with two integerN(1<=N<=100000),M(0<=M<=200000),indicating that there are N townsand M roads in Ant Country.Followed by M lines,each line contains two integersa,b,(1<=a,b<=N) indicating that there is a road connecting town a andtown b.No two roads will be the same,and there is no road connecting the sametown.

 

 

Output

For each test case ,output the leastgroups that needs to form to achieve their goal.

 

 

SampleInput

3 3

1 2

2 3

1 3

 

4 2

1 2

3 4

 

 

SampleOutput

1

2

 

Hint

New ~~~ Notice: if there are no roadconnecting one town ,tony may forget about the town.

In sample 1,tony and his friends justform one group,they can start at either town 1,2,or 3.

In sample 2,tony and his friends mustform two group.

 


这是一个关于一笔画的问题,先用并查集维护看看有几个联通块,再统计联通块中奇点的个数,奇点为0就可以一笔画成,否则就要用奇点数/2笔画成(因为每两个奇点之间需要画一笔)

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 100050
using namespace std;

int n,m,tot,ans;
int res[N],fa[N],ji[N],du[N],visit[N];

int getfa(int x){return fa[x] == x?x:fa[x]=getfa(fa[x]);}
inline int read()
{
    int ret=0;char ch=getchar();
    while(ch<'0' || ch>'9') ch=getchar();
    while(ch>='0' && ch<='9') ret=ret*10+ch-'0',ch=getchar();
    return ret;
}
inline void inti()
{
        tot=0;ans=0;
        for (int i=1;i<=N;i++)
        {
            du[i]=0;visit[i]=0;
            res[i]=0;ji[i]=0;
        }
        for (int i=1;i<=n;i++) fa[i]=i;
}

int main()
{
    while(scanf("%d%d",&n,&m) != EOF)
    {
        inti();
        for (int i=0;i<m;i++)
        {
            int x,y;
            x=read();y=read();
            int p=getfa(x),q=getfa(y);
            if (p != q) fa[p]=q;
            du[x]++;du[y]++;
        }
        for (int i=1;i<=n;i++)
        {
            int ba=getfa(i);
            if (!visit[ba]) visit[ba]=1,res[tot++]=ba;
            if (du[i]&1) ji[ba]++;
        }
        for (int i=0;i<tot;i++)
        {
            if (!du[res[i]]) continue;
            if (!ji[res[i]]) ans++;
            else ans+=ji[res[i]]/2;
        }
        printf("%d\n",ans);
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值