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 いまが最高! だってだって、いまが最高!
原文地址:https://www.cnblogs.com/nanjolno/p/14761842.html