给你无向图的 N个点和 M条边,保证这 M条边都不同且不会存在同一点的自环边,现在问你至少要几笔才能所有边都画一遍。(一笔画的时候笔不离开纸)
#include<bits/stdc++.h> #define re return #define inc(i,l,r) for(int i=l;i<=r;++i) using namespace std; template<typename T>inline void rd(T&x) { char c;bool f=0; while((c=getchar())<'0'||c>'9')if(c=='-')f=1; x=c^48; while((c=getchar())>='0'&&c<='9')x=x*10+(c^48); if(f)x=-x; } const int maxn=100005; int n,m,d[maxn],fa[maxn],cnt[maxn]; inline int find(int x) { re x==fa[x]?x:fa[x]=find(fa[x]); } int main() { int x,y,f1,f2; while(~(scanf("%d%d",&n,&m))) { inc(i,1,n)fa[i]=i,cnt[i]=d[i]=0; if(!m) { printf("0 "); continue; } inc(i,1,m) { rd(x),rd(y); ++d[x];++d[y]; f1=find(fa[x]);f2=find(fa[y]); if(f1!=f2)fa[f1]=f2; //并查集判连通 } inc(i,1,n) { if(d[i]&1) ++cnt[find(fa[i])];//累加到所属并查集里 } int ans=0; inc(i,1,n) if(fa[i]==i&&d[i]&&!cnt[i])ans+=1; //如果该并查集有边但是欧拉回路 ans+1 else ans+=(cnt[i]>>1); //否则这个并查集以欧拉路径来求笔画数 printf("%d ",ans); } re 0; }