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\n");
for(int i=1;i<=m;i++)
{
if(cs[i])
printf("%d %d\n",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\n");
else
{
printf("Yes\n");
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\n",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 いまが最高!
だってだって、いまが最高!