J - 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.

题意:有一个图(非联通)每个边只能走一遍,问你多少笔能走完

题解:对于一个联通无向图来说,如果没有奇度顶点,说明有欧拉回路,一笔就能走完

如果没有欧拉回路,笔画数=奇度顶点数/2

题目没说联不联通,所以用并查集判断一下每个连通块有多少奇度顶点

需要特别注意的是,一个顶点的连通块直接跳过,因为不需要笔画数

#include <bits/stdc++.h>
#define maxn 100000+5
using namespace std;
int  pre[maxn],cnt[maxn],d[maxn];
int vis[maxn],n,m;
int Find(int x){  
    int r=x;  
    while(r!=pre[r])  
        r=pre[r];
    int i=x,j;  
    while(pre[i]!=r){  
        j=pre[i];  
        pre[i]=r;  
        i=j;
    }  
    return r;  
}
void mix(int x,int y){  
    int fx=Find(x),fy=Find(y);
    if(fx!=fy){
        pre[fy]=fx;  
    }  
}
void init(){
    for(int i=0;i<=n;i++)pre[i]=i;
    memset(cnt,0,sizeof(cnt));
    memset(d,0,sizeof(d));
    memset(vis,0,sizeof(vis));
}

int main()
{
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        for(int i=0;i<m;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            d[u]++,d[v]++;
            if(Find(u)!=Find(v))mix(u,v);
        }
        vector<int>v;
        for(int i=1;i<=n;i++){ 
            int k=Find(i);
            if(d[i]%2==1)cnt[k]++;
            vis[k]++;
        }
        int ans=0;
        for(int i=1;i<=n;i++){
            if(vis[i]>1){
                if(cnt[i])ans+=cnt[i]/2;
                else  ans++;
            }
        }
        printf("%d\n",ans);
    }   
    return 0;
}

 

全部评论

相关推荐

头像
2025-12-02 21:34
中南大学 Java
我这边应该算是华为第一批开奖的了,还是要11月底才开,不过今年的流程整体比去年确实要开得早,这一点还是值得表扬的。然后华为也确实很有诚意,给我这样bg的硕鼠开了15a,并且base地还是在杭州,应该是buff拉满了,但凡其他公司开的没这个高,and对象没签上海,可能真选择成为华孝子了。虽然很有诱惑力,但是这个15a的offer里面确实还是有猫腻的:1.&nbsp;薪资构成是这样的,15a&nbsp;=&nbsp;(基本工资+绩效工资)*12&nbsp;+&nbsp;10w年终,虽然绩效工资hr说100%能拿满,年终大部分都能拿满,绩效工资能拿满我可能还选择相信,但10w年终还能拿满,这我就存疑了。反正看了一圈别家的公司报价都是报一般情况下能拿多少年终,比如美团0-6个月,就报3.5个月,但是华似乎是喜欢往最高了报,所以估计10w年终拿满应该也是极少数人。2.&nbsp;公积金只交5%,并且缴纳基数还只是按基本工资交的,这里看似每个月到手的钱变多了,但是总体算下来,可能一年比别家就少拿1-2w。3.&nbsp;月末周六要加班,可以选择调休或双倍加班费,并且平常应该也会加班,感觉不大会像hr说的124能8.30下班,35能5.30下班的,云计算bu强度应该还算比较好的,估计一般情况下9-9-5吧,但是不知道并入ict后会如何。4.&nbsp;还有相关的业务线,听说8,9月份云计算bu内部已经调整了一波,好像还要并入ict下面了,感觉未来的不确定性也比较大。5.&nbsp;华为的认可度应该比不过传统的互联网大厂,技术的前瞻性应该也比不过(个人看法)。6.&nbsp;培养和升职,感觉美团可能更有说法,毕竟见到过1年升L6的,甚至还有两年升L7的,对华为的了解相对较少,只知道华为可能相对稳定一些?毕竟4年一签?综上,还是决定放弃华,准备去团吧,自己选的路,希望不会后悔吧。
变形钢筋:这个薪资结构,年终奖是画大饼啊
OC/开奖
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务