Ant Trip(画几笔)

给你无向图的 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\n");
            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\n",ans);
    }

    re 0;
} 

 

Guess you like

Origin www.cnblogs.com/lsyyy/p/11421825.html
ANT
ANT