题意:是否能从给出的图中得出一个生成树,使树中1的度数为k
(1) 若原图中1的度数小于k ,显然不行
(2)若原图中1的度数大于k,我们需要删除一部分与1相连的边,先把与1相连的所有边删除,剩下我们要添加的1边就需要将这些连通块连接起来,如果连通块个数大于k显然也不行
(3)将所有连接起连通块的1边加入答案,之后再随便选几个边直到满足1的度数为k为止,再次根据已经添加到答案的边做一次并茶几,对剩下的不包括1的边随便加直到连通为止
int n,m,k,f[MAXN];
int find(int x){return x==f[x]?x:f[x]=find(f[x]);}
vector<pii>ans,mp,mp1,noan;
signed main()
{
cin>>n>>m>>k;
rpp(i,n) f[i]=i;
rpp(i,m)
{
int x,y;cin>>x>>y;
if(x==1||y==1) mp1.push_back(make_pair(x,y));
else
{
mp.push_back(make_pair(x,y));
if(find(x)!=find(y)) f[find(x)]=find(y);
}
}
if(sz(mp1)<k) cout<<"NO\n";
else
{
int cnt=0;
for(auto it:mp1)//用1的边把所有的连通分量连接起来
{
if(find(it.first)!=find(it.second))
{
f[find(it.first)]=find(it.second);
ans.push_back(it);
++cnt;
}
else noan.push_back(it);//暂时没有连接的边
}
if(cnt>k) cout<<"NO\n";
else
{
for(int i=0;i<k-cnt;++i ) ans.push_back(make_pair(noan[i].first,noan[i].second));
rpp(i,n) f[i]=i;
for(auto it:ans)
if(find(it.first)!=find(it.second))
f[find(it.first)]=f[find(it.second)];
for(auto it:mp)
if(find(it.first)!=find(it.second))
f[find(it.first)]=f[find(it.second)],ans.push_back(it);
cout<<"YES\n";
for(auto it:ans) cout<<it.first<<" "<<it.second<<endl;
}
}
return 0;
}