http://acm.hdu.edu.cn/showproblem.php?pid=3018
题意:
给出一张图,不能走重复边,可以几笔画遍历完所有的边
连通子图内如果没有度数为奇数的点,这个子图可以一笔画
否则,需要奇度数点的个数/2 笔
因为每笔可以消除两个点的奇度
#include<cstdio> #include<iostream> using namespace std; #define N 100001 #define M 200001 int fa[N]; int sum[N],d[N]; int odd[N]; struct node { int u,v; }e[M]; void read(int &x) { x=0; char c=getchar(); while(!isdigit(c)) c=getchar(); while(isdigit(c)) { x=x*10+c-‘0‘; c=getchar();} } int find(int i) { return fa[i]==i ? i : fa[i]=find(fa[i]); } int main() { int n,m,u,v; int ans; while(scanf("%d",&n)!=EOF) { read(m); for(int i=1;i<=m;++i) read(e[i].u),read(e[i].v); for(int i=1;i<=n;++i) fa[i]=i,sum[i]=1,odd[i]=d[i]=0; for(int i=1;i<=m;++i) { d[e[i].u]++; d[e[i].v]++; u=find(e[i].u); v=find(e[i].v); if(u!=v) sum[v]+=sum[u],fa[u]=v; } ans=0; for(int i=1;i<=n;++i) if(d[i]&1) odd[find(i)]++; for(int i=1;i<=n;++i) if(find(i)==i && d[i]) { if(!odd[i]) ans++; else ans+=odd[i]/2; } printf("%d\n",ans); } }