Ant Trip(欧拉回路+并查集)
Posted handsome-zlk
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Ant Trip(欧拉回路+并查集)相关的知识,希望对你有一定的参考价值。
Ant Trip
输入格式
输出格式
样例
数据范围与提示
1≤N≤10^5,0≤M≤2×105,1<=a,b<=N
思路:
It‘s also a good problem
原图应是由若干个无向连通图组成的
当这个无向连通图只有一个点时,这是一个孤立点,不做操作
当这个无向连通图是一条欧拉回路或欧拉路径时,只需要一笔画即可,sum++;
当这个无向连通图有大于2个奇度点,需要用奇度点的个数的二分之一笔画完,为什么?因为一笔可以消掉两个奇度点。由于对称性的缘故,一条边的左右两端点度数分别加一,倘若原来两点都是奇度点,则两端点都会变成偶度点,反之亦然,倘若两端点度数的奇偶性不同,一者为奇一者为偶,与这两点对应的点一定有奇数个奇度点,所以一个无向连通图中不可能存在奇数个奇度点,所以只需/2即可
当然可以用并查集维护每个无向连通图
上代码
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> #define rep(i,a,b) for(int i=a;i<=b;i++) using namespace std; int n,m,fa[100040],de[100004],sum[100040],num[100004]; void init(){ memset(de,0,sizeof(de)); memset(sum,0,sizeof(sum)); memset(num,0,sizeof(num)); rep(i,1,n) fa[i]=i; } int find(int x){ if(fa[x]==x) return x; else return fa[x]=find(fa[x]); } int main(){ freopen("1.txt","r",stdin) while(~scanf("%d%d",&n,&m)){ int s=0; init(); rep(i,1,m){ int a,b; scanf("%d%d",&a,&b); ++de[a]; ++de[b]; a=find(a); b=find(b); if(a!=b) fa[a]=b; } rep(i,1,n){ if(de[i]&1) sum[find(i)]++; num[find(i)]++; } rep(i,1,n){ if(num[i]==0 || num[i]==1) continue; else if(sum[i]==0) ++s; else s+=(sum[i]/2); } printf("%d ",s); } return 0; }
以上是关于Ant Trip(欧拉回路+并查集)的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3018 Ant Trip (并查集求连通块数+欧拉回路)
HDU 3018 Ant Trip (欧拉路的个数 并查集)