列表

详情


NC245488. st-Spanning Tree

描述

给定一个n个点m条边的无向联通图,没有重边和自环。给定s和t,求一棵生成树,使得s,t的度数不超过ds,dt。
若有解,输出“Yes”和方案,若无解,输出“No”。

输入描述

第一行两个整数
接下来m行每行两个整数表示一条边。
最后一行四个整数s , t , , ( , , ).

输出描述

如果有解,请在第一行输出Yes,之后输出n-1行,每行两个数字代表生成树中的一条边。
如果无解,请输出No。

示例1

输入:

3 3
1 2
2 3
3 1
1 2 1 1

输出:

Yes
3 2
1 3

示例2

输入:

7 8
7 4
1 3
5 4
5 7
3 2
2 4
6 1
1 2
6 4 1 4

输出:

Yes
1 3
5 7
3 2
7 4
2 4
6 1

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(clang++ 11.0.1) 解法, 执行用时: 160ms, 内存消耗: 9680K, 提交时间: 2022-11-23 13:45:19

#include<bits/stdc++.h>
using namespace std;
const int N = 400010;
int p[N];
int n,m,s,t,ds,dt;
struct node
{
    int x,y,use,w;
    bool operator < (const node &W) const
    {
        return w<W.w;
    }
}e[N];

int find(int x)
{
    if(p[x]!=x) p[x]=find(p[x]);
    return p[x];
}

signed main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) p[i]=i;
    for(int i=1;i<=m;i++)
    {
        int u,v;
        cin>>u>>v;
        e[i]={u,v,0,0};
    }
    cin>>s>>t>>ds>>dt;
    int dss=0,dtt=0;
    int vals,valt;
    if(ds>dt) vals=1,valt=2;
    else vals=2,valt=1;
    for(int i=1;i<=m;i++)
    {
        e[i].use=0;
        if(e[i].x==s||e[i].y==s) e[i].w=vals;
        if(e[i].x==t||e[i].y==t) e[i].w=valt;
    }
    int cnt=0;
    sort(e+1,e+1+m);
    for(int i=1;i<=m;i++)
    {
        int u=e[i].x,v=e[i].y;
        if(e[i].w==0)
        {
            if(find(u)!=find(v))
            {
                cnt++;
                e[i].use=1;
                p[find(v)]=find(u);
            }
        }
        else
        {
            if(find(u)!=find(v))
            {
                if(u==s||v==s)
                {
                    if(dss==ds) continue;
                    dss++;
                }
                if(v==t||u==t)
                {
                    if(dtt==dt) continue;
                    dtt++;
                }
                cnt++;
                e[i].use=1;
                p[find(v)]=find(u);
            }
        }
    }
    if(dss<=ds&&dtt<=dt&&cnt==n-1)
    {
        cout<<"Yes\n";
        for(int i=1;i<=m;i++)
        {
            if(e[i].use==1)
                cout<<e[i].x<<" "<<e[i].y<<'\n';
        }
    }
    else{
    for(int i=1;i<=n;i++) p[i]=i;
    dss=0,dtt=0;
    int vals,valt;
    if(ds>=dt) vals=1,valt=2;
    else vals=2,valt=1;
    for(int i=1;i<=m;i++)
    {
        e[i].use=0;
        if(e[i].x==s||e[i].y==s) e[i].w=vals;
        if(e[i].x==t||e[i].y==t) e[i].w=valt;
    }
    int cnt=0;
    sort(e+1,e+1+m);
    for(int i=1;i<=m;i++)
    {
        int u=e[i].x,v=e[i].y;
        if(e[i].w==0)
        {
            if(find(u)!=find(v))
            {
                cnt++;
                e[i].use=1;
                p[find(v)]=find(u);
            }
        }
        else
        {
            if(find(u)!=find(v))
            {
                if(u==s||v==s)
                {
                    if(dss==ds) continue;
                    dss++;
                }
                if(v==t||u==t)
                {
                    if(dtt==dt) continue;
                    dtt++;
                }
                cnt++;
                e[i].use=1;
                p[find(v)]=find(u);
            }
        }
    }
         if(dss<=ds&&dtt<=dt&&cnt==n-1)
    {
        cout<<"Yes\n";
        for(int i=1;i<=m;i++)
        {
            if(e[i].use==1)
                cout<<e[i].x<<" "<<e[i].y<<'\n';
        }
    }else cout<<"No"<<endl;
    }
}

上一题