CodeForces - 1133F2 Spanning Tree with One Fixed Degree (并茶几,生成树)

🚨 🚨 🚨

题意:是否能从给出的图中得出一个生成树,使树中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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值