HDU3018-Ant Trip(无向图 欧拉路径)

题目链接

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.

https://i-blog.csdnimg.cn/blog_migrate/87f4654e3e9f30d385bf389cf2483a1a.jpeg

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.


题目大意

给了一些图,求一笔画的最小笔数。此题中一笔画的规则是不能走重复的路径,即不能返回走

They intend to visit every road , and every road must be visited for exact one time,这句是关键,每一条路都要走,但是每次走的时候,每条路只能走一次。

思路

欧拉路径: 通过图中每条边且只通过一次,并且经过每一顶点的路径。

欧拉回路: 通过图中每条边且只通过一次,并且经过每一顶点的回路。

半欧拉图:存在欧拉路径但不存在欧拉回路的图。

欧拉图:存在欧拉回路的图。

 

无向图是否具有欧拉路径或回路的判定:

欧拉路径:图连通;图中只有2个度为奇数的节点

欧拉回路:图连通;图中所有节点度均为偶数

 

有向图是否具有欧拉路径或回路的判定:

欧拉路径:基图连通;1个端点入度比出度大1,一个端点入度比出度小1,其余点入度等于出度。

欧拉回路:基图连通;所有节点入度等于出度

**基图:有向图的基础上去掉方向

 

一个连通图,如果可以走重复的路,一笔就可以画完;如果不能走重复的路,就需要根据这个连通图的度数为奇数的点的个数来判断。如果没有度数为奇数的点,则一笔可以画;如果度数为奇数的点为n个(n>0,其实n也一定是偶数),那么需要n/2笔可以画完。

至于为什么是n/2,度数为奇数的肯定得是起点终点,可以简单理解为有n/2对起点终点,所以需要n/2次笔画。

用并查集来判断连通图,num[ ]记录一个连通图有多少个点(题目中说孤立的点不需要考虑),odd[ ]记录连通图中度数为奇数的点的个数,degree[ ]记录点的度数.

代码参考


#include <bits/stdc++.h>

using namespace std;
const int Max = 100010;
int f[Max],num[Max],odd[Max],degree[Max];
//f[] 并查集   num[] 一个联通块的点的个数
//odd[] 一个联通块的度数为奇数的点的个数
//degree[] 点的度数
int m,n;

int Find(int x)
{
    if(f[x]==x) return x;
    return f[x] = Find(f[x]);
}

void Union(int x,int y)
{
    int a,b;
    a = Find(x); b = Find(y);
    if(a!=b) f[a] = b;
}

void init()
{
    memset(f,0,sizeof(f));
    memset(num,0,sizeof(num));
    memset(odd,0,sizeof(odd));
    memset(degree,0,sizeof(degree));
    for(int i=1;i<=n;i++){
        f[i] = i;
    }
}

int main() {
    while(~scanf("%d%d",&n,&m))
    {
        init();
        for(int i=0;i<m;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            Union(x,y);
            degree[x]++;
            degree[y]++;
        }
        for(int i=1;i<=n;i++){
            num[Find(i)]++;
            if(degree[i]&1) odd[Find(i)]++;
        }
        int ans = 0;
        for(int i=1;i<=n;i++){
            if(num[i]<=1) continue; //1个 是孤立的点
            if(odd[i]==0) ans += 1;
            else ans += odd[i]/2;
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值