传送机

问题 F: 传送机

时间限制: 1.000 Sec  内存限制: 128 MB
提交 状态

题目描述

黄黄同学要到清华大学上学去了。
黄黄同学很喜欢清华大学的校园,每次去上课时总喜欢把校园里面的每条路都走一遍,当然,黄黄同学想每条路也只走一遍。我们一般人很可能对一些地图是办不到每条路走一遍且仅走一遍的,但是黄黄同学有个传送机,他可以任意地将一个人从一个路口传送到任意一个路口。
可是,每传送一次是需要耗费巨大的内力的,黄黄同学希望可以用最少的传送次数完成游遍校园,你能帮助他吗?
因为黄黄同学只是游历校园,于是我们可以认为黄黄同学可以从任意点开始,到任意点结束。
注意:不必经过所有的点。

输入

输入第一行一个整数N,表示黄黄的校园里一共有多少路口。
第二行一个整数M,表示路口之间有M条路。
后面M行,每行两个整数a、b,表示a与b之间有一条路,且路是双向的。

输出

输出一行一个整数S,表示黄黄同学最少的传送次数。

样例输入 Copy

3 
2 
1 2 
2 3 

样例输出 Copy

0

提示

对于100%的数据满足:N<=100000,M<=500000,1<=a,b<=N。
 
 
这里主要记录下自己的思维的错误之处。这个题是问补几条边成为一个欧拉通路。第一次想的做法是统计奇度数点的个数然后-1/2输出。在一些样例里没有问题。
但这忽略了,两个欧拉通路不连通也需要额外一条边来进行连。这也是本题并查集的应用之处
 
 
查看代码
 #include<iostream>
#pragma GCC optimize(2)
using namespace std;
int n,m,ans;
int ver[1000001],f[1000001],a[1000001];
int fin(int x)
{
	if(f[x]==x)return x;
	return f[x]=fin(f[x]);
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)f[i]=i;
	while(m--)
	{
		int x,y;
		cin>>x>>y;
		ver[x]++;
		ver[y]++;
		int a=fin(x),b=fin(y);
		if(a!=b)f[b]=a;
	}
	for(int i=1;i<=n;i++)
		if(ver[i]%2)
		a[fin(i)]++;
	for(int i=1;i<=n;i++)
		if(ver[i]>0&&fin(i)==i)
			ans=ans+1+max(0,(a[i]-2)/2);
	ans--;//第一个进入不需要传送
	if(ans<0)ans=0;//如果没有路传送次数为0
	cout<<ans;
	return 0;
}
posted @ 2022-12-28 20:23  qbning  阅读(29)  评论(0编辑  收藏  举报
描述