• 2020ICPC南京D. Degree of Spanning Tree


    #include<bits/stdc++.h>
    using namespace std;
    struct edge{
        int st,de;
    }eg[300005];
    struct front_star{
        int to,next;
    }e[400005];
    int T,n,m,cnt=0;
    int cs[200005],fa[100005],deg[100005],head[100005],nox[100005];
    inline int read()
    {
        int X=0,w=0; char ch=0;
        while(!isdigit(ch)) {w|=ch=='-';ch=getchar();}
        while(isdigit(ch)) X=(X<<3)+(X<<1)+(ch^48),ch=getchar();
        return w?-X:X;
    }
    inline void write(int x)
    {
         if(x<0) putchar('-'),x=-x;
         if(x>9) write(x/10);
         putchar(x%10+'0');
    }
    bool check(int t)
    {
        int a=eg[t].de,b=eg[t].st;
        if(nox[a]!=1&&nox[b]!=1)
        {
            if(deg[a]+1>n/2||deg[b]+1>n/2)
                return false;
            else
                return true;
        }
        int da=deg[a],db=deg[b];
        if(nox[a]==1&&nox[b]==1)
        {
            if(da>db)
                da--;
            else
                db--;
        }
        else
        {
            if(nox[a]==1)
                da--;
            if(nox[b]==1)
                db--;
        }
        if(da+1>n/2||db+1>n/2)
            return false;
        else
            return true;
    }
    void addedge(int u,int v)
    {
        cnt++;
        e[cnt].to=v;
        e[cnt].next=head[u];
        head[u]=cnt;
    }
    int findx(int a)
    {
    	if(a==fa[a]) return a;
    	else
    	{
    		int x=findx(fa[a]);
    		fa[a]=x;
    		return x;
    	}
    }
    void dfs(int u,int f,int x)
    {
        fa[u]=x;
        for(int i=head[u];~i;i=e[i].next)
        {
            int v=e[i].to;
            if(v==f)
                continue;
            dfs(v,u,x);
        }
    }
    int main()
    {
        scanf("%d",&T);
        memset(head,-1,sizeof(head));
        memset(cs,0,sizeof(cs));
        memset(deg,0,sizeof(deg));
        memset(nox,-1,sizeof(nox));
        while(T--)
        {
            cnt=0;
    
            scanf("%d%d",&n,&m);
            for(int i=1;i<=n;i++)
                fa[i]=i;
            for(int i=1;i<=m;i++)
            {
                int a,b;
                scanf("%d%d",&a,&b);
                eg[i].st=a;
                eg[i].de=b;
                int af=findx(a);
                int bf=findx(b);
                if(af!=bf)
                {
                    fa[af]=bf;
                    deg[a]++;
                    deg[b]++;
                    addedge(a,b);
                    addedge(b,a);
                    cs[i]=1;
                }
            }
            int root=0;
            for(int i=1;i<=n;i++)
            {
                if(deg[i]>n/2)
                {
                    root=i;
                    break;
                }
            }
            if(!root)
            {
                printf("Yes
    ");
                for(int i=1;i<=m;i++)
                {
                    if(cs[i])
                        printf("%d %d
    ",eg[i].st,eg[i].de);
                }
            }
            else
            {
                for(int i=head[root];~i;i=e[i].next)
                {
                    int v=e[i].to;
                    nox[v]=1;
                    fa[v]=v;
                    dfs(v,root,v);
                }
                for(int i=1;i<=m;i++)
                {
                    if(deg[root]<=n/2)
                        break;
                    if(!cs[i])
                    {
                        int a=eg[i].st;
                        int b=eg[i].de;
                        int af=findx(a);
                        int bf=findx(b);
                        if(a==root||b==root)
                            continue;
                        if(af!=bf&&check(i))
                        {
                            int nr,ns;
                            if(deg[af]<deg[bf])
                            {
                                nr=af;
                                ns=bf;
                            }
                            else
                            {
                                nr=bf;
                                ns=af;
                            }
                            fa[ns]=nr;
                            nox[ns]=0;
                            cs[i]=1;
                            deg[a]++;
                            deg[b]++;
                            deg[root]--;
                            deg[ns]--;
                        }
                    }
                }
                if(deg[root]>n/2)
                    printf("No
    ");
                else
                {
                    printf("Yes
    ");
                    for(int i=1;i<=m;i++)
                    {
                        if(cs[i])
                        {
                            int a=eg[i].st;
                            int b=eg[i].de;
                            if((a==root&&nox[b]==0)||(b==root&&nox[a]==0))
                                continue;
                            printf("%d %d
    ",a,b);
                        }
                    }
                }
            }
            for(int i=0;i<=n;i++)
            {
                head[i]=-1;
                nox[i]=-1;
                deg[i]=0;
            }
            for(int i=1;i<=m;i++)
                cs[i]=0;
        }
        return 0;
    }
    
    小鳥の翼がついに大きくなって , 旅立ちの日だよ , 遠くへと広がる海の色暖かく , 夢の中で描いた絵のようなんだ , 切なくて時をまきもどしてみるかい ? No no no いまが最高! だってだって、いまが最高!
  • 相关阅读:
    Codeforces 627A XOR Equation(思路)
    Codeforces 633C Spy Syndrome 2(DP + Trie树)
    BZOJ 1982 [Spoj 2021]Moving Pebbles(博弈论)
    BZOJ 3676 [Apio2014]回文串(回文树)
    BZOJ 3790 神奇项链(manacher+DP+树状数组)
    Codeforces 449D Jzzhu and Numbers(高维前缀和)
    SPOJ Time Limit Exceeded(高维前缀和)
    BZOJ 4031 [HEOI2015]小Z的房间(Matrix-Tree定理)
    BZOJ 3809 Gty的二逼妹子序列(莫队+分块)
    BZOJ 3544 [ONTAK2010]Creative Accounting(set)
  • 原文地址:https://www.cnblogs.com/nanjolno/p/14761842.html
Copyright © 2020-2023  润新知