1530:Ant Trip
时间限制: 1000 ms 内存限制: 32768 KB
提交数: 148 通过数: 69
【题目描述】
原题来自:2009 Multi-University Training Contest 12 - Host by FZU
给你无向图的 N 个点和 M 条边,保证这 M 条边都不同且不会存在同一点的自环边,现在问你至少要几笔才能所有边都画一遍。(一笔画的时候笔不离开纸)
【输入】
多组数据,每组数据用空行隔开。
对于每组数据,第一行两个整数 N,M 表示点数和边数。接下去 M 行每行两个整数 a,b,表示 a,b 之间有一条边。
【输出】
对于每组数据,输出答案。
【输入样例】
3 3
1 2
2 3
1 3
4 2
1 2
3 4
【输出样例】
1
2
【提示】
数据范围与提示:
1≤N≤105,0≤M≤2×105,1≤a,b≤N
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n,m,du[N],fa[N],x,y,num[N],sum[N];
int Find(int x)
{
if(x!=fa[x])
fa[x]=Find(fa[x]);
return fa[x];
}
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
while(cin >> n >> m)
{
for(int i=1;i<=n;i++)
fa[i]=i;
memset(du,0,sizeof(du));
memset(num,0,sizeof(num));
memset(sum,0,sizeof(sum));
while(m--)
{
cin >> x >> y;
du[x]++,du[y]++;
int u=Find(x),v=Find(y);
if(u!=v)
fa[u]=v;
}
for(int i=1;i<=n;i++)
{
x=Find(i);
num[x]++;//一个团队人数
if(du[i]&1)
sum[x]++;//队长负责
}
int res=0;
for(int i=1;i<=n;i++)//各队长
{
if(num[i]<=1)
continue;
if(sum[i]==0)
res++;
else
res+=sum[i]/2;
}
cout << res << endl;
}
return 0;
}