链接
https://codeforces.com/contest/1133/problem/F2
题解
如果
1
1
1的度数小于
D
D
D,那么直接无解
先把
1
1
1删掉
然后求一下有多少连通分量
假设连通分量个数是
c
n
t
cnt
cnt,如果
c
n
t
>
D
cnt>D
cnt>D那么无解
然后在每个联通块里找一个点,连接到
1
1
1上,这样就保证了连通性,然后再在
1
1
1剩下的出边里随便选
D
−
c
n
t
D-cnt
D−cnt条连上
最后
d
f
s
dfs
dfs构造出整棵生成树即可
代码
#include <bits/stdc++.h>
#define maxn 400010
#define cl(x) memset(x,0,sizeof(x))
#define eps 1e-10
using namespace std;
typedef long long ll;
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
ll f[maxn], head[maxn], nex[maxn], to[maxn], etot, N, M, deg[maxn], vis[maxn], D, spcial[maxn];
set< pair<ll,ll> > ans;
set< ll > s[maxn];
ll find(ll x){return f[x]==x?x:f[x]=find(f[x]);}
void merge(ll a, ll b){f[find(a)]=find(b);}
void adde(ll a, ll b){to[++etot]=b;nex[etot]=head[a];head[a]=etot;}
void init()
{
ll i, a, b;
N=read(), M=read(), D=read();
for(i=1;i<=M;i++)a=read(), b=read(), adde(a,b), adde(b,a), deg[a]++, deg[b]++;
for(i=1;i<=N;i++)f[i]=i;
}
void dfs(ll pos)
{
ll p;
vis[pos]=1;
for(p=head[pos];p;p=nex[p])
if(!vis[to[p]])
{
merge(to[p],pos);
dfs(to[p]);
}
}
void dfs2(ll pos)
{
ll p;
vis[pos]=1;
for(p=head[pos];p;p=nex[p])
if(!vis[to[p]])
{
ans.insert(make_pair(min(pos,to[p]),max(pos,to[p])));
dfs2(to[p]);
}
}
void work()
{
ll i, j, res=D, p, cnt=0;
if(deg[1]<D)
{
printf("NO");
return;
}
vis[1]=1;
for(p=head[1];p;p=nex[p])
{
if(!vis[to[p]])
{
dfs(to[p]), cnt++;
ans.insert(make_pair(1,to[p]));
}
else s[find(to[p])].insert(to[p]);
}
if(cnt>D)
{
printf("NO");
return;
}
cl(vis), vis[1]=1;
for(p=head[1];p;p=nex[p])
{
if(find(to[p])==to[p])
{
ans.insert(make_pair(1,to[p]));
vis[to[p]]=1;
res--;
}
}
for(p=head[1];p and res;p=nex[p])
{
if(find(to[p])!=to[p])
{
ans.insert(make_pair(1,to[p]));
vis[to[p]]=1;
res--;
}
}
for(p=head[1];p;p=nex[p])
{
if(ans.find(make_pair(1,to[p]))!=ans.end())
{
dfs2(to[p]);
}
}
printf("YES\n");
for(set< pair<ll,ll> >::iterator it=ans.begin();it!=ans.end();it++)
{
printf("%lld %lld\n",it->first,it->second);
}
}
int main()
{
init();
work();
return 0;
}