zoukankan      html  css  js  c++  java
  • CodeForces 723F st-Spanning Tree

    $dfs$,构造。

    类似于$k$度限制生成树的想法,可以将$s$和$t$先从图中删去,将剩下的部分求连通块,每个连通块内部很容易构造生成树,每个连通块缩成一个点来处理。

    连通块分三种:

    $1$.只与$s$有边

    $2$.只与$t$有边

    $3$.与$s$和$t$都有边

    前两种没办法,只能和$s$和$t$相连。如果没有第三种,那么$s$和$t$之前需要连一条边。如果有第三种,在第三种里面选出一个来和$s$、$t$连,其余的当做第一种和第二种处理。

    连边的过程中判断$s$和$t$的度是否满足条件即可。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<ctime>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-10;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c = getchar();
        x = 0;
        while(!isdigit(c)) c = getchar();
        while(isdigit(c))
        {
            x = x * 10 + c - '0';
            c = getchar();
        }
    }
    
    struct Edge
    {
        int a,b,nx;
    }e[800010];
    int h[200010];
    int n,m,sz,s,t,ds,dt;
    int belong[200010],block;
    vector<int>ansx,ansy;
    
    struct X
    {
        int e1,e2;
    }w[200010];
    
    set<int>SS,TT;
    
    void add(int a,int b)
    {
        e[sz].a=a; e[sz].b=b; e[sz].nx=h[a]; h[a]=sz++;
    }
    
    void dfs(int x)
    {
        belong[x]=block;
        for(int i=h[x];i!=-1;i=e[i].nx)
        {
            int to=e[i].b;
            if(belong[to]!=0) continue;
            if(to==s) continue;
            if(to==t) continue;
    
            ansx.push_back(x);
            ansy.push_back(to);
    
            dfs(to);
        }
    }
    
    int main()
    {
        cin>>n>>m; memset(h,-1,sizeof h);
        for(int i=1;i<=m;i++)
        {
            int a,b; cin>>a>>b;
            add(a,b); add(b,a);
        }
        cin>>s>>t>>ds>>dt;
    
        for(int i=1;i<=n;i++)
        {
            if(i==s) continue;
            if(i==t) continue;
            if(belong[i]!=0) continue;
            block++; dfs(i);
        }
    
        for(int i=1;i<=block;i++) w[i].e1=w[i].e2=-1;
    
        for(int i=0;i<sz;i=i+2)
        {
            if(e[i].a==s&&(e[i].b!=s&&e[i].b!=t))
            {
                SS.insert(belong[e[i].b]);
                if(w[belong[e[i].b]].e1==-1) w[belong[e[i].b]].e1=i;
            }
            if(e[i].b==s&&(e[i].a!=s&&e[i].a!=t))
            {
                SS.insert(belong[e[i].a]);
                if(w[belong[e[i].a]].e1==-1) w[belong[e[i].a]].e1=i;
            }
            if(e[i].a==t&&(e[i].b!=s&&e[i].b!=t))
            {
                TT.insert(belong[e[i].b]);
                if(w[belong[e[i].b]].e2==-1) w[belong[e[i].b]].e2=i;
            }
            if(e[i].b==t&&(e[i].a!=s&&e[i].a!=t))
            {
                TT.insert(belong[e[i].a]);
                if(w[belong[e[i].a]].e2==-1) w[belong[e[i].a]].e2=i;
            }
        }
    
        int sum=0; vector<int>tmp;
        for(int i=1;i<=block;i++)
        {
            if(SS.count(i)&&TT.count(i)) { tmp.push_back(i); continue; }
            if(SS.count(i))
            {
                ansx.push_back(e[w[i].e1].a);
                ansy.push_back(e[w[i].e1].b);
                ds--;
            }
            else
            {
                ansx.push_back(e[w[i].e2].a);
                ansy.push_back(e[w[i].e2].b);
                dt--;
            }
        }
    
        if(tmp.size()==0)
        {
            ansx.push_back(s);
            ansy.push_back(t);
            ds--; dt--;
        }
    
        else
        {
            ansx.push_back(e[w[tmp[0]].e1].a);
            ansy.push_back(e[w[tmp[0]].e1].b);
            ansx.push_back(e[w[tmp[0]].e2].a);
            ansy.push_back(e[w[tmp[0]].e2].b);
    
            ds--; dt--;
    
            for(int i=1;i<tmp.size();i++)
            {
                if(ds>0)
                {
                    ansx.push_back(e[w[tmp[i]].e1].a);
                    ansy.push_back(e[w[tmp[i]].e1].b);
                    ds--;
                }
                else if(dt>0)
                {
                    ansx.push_back(e[w[tmp[i]].e2].a);
                    ansy.push_back(e[w[tmp[i]].e2].b);
                    dt--;
                }
            }
    
        }
    
        if(ds<0||dt<0||ansx.size()!=n-1) printf("No
    ");
        else
        {
            printf("Yes
    ");
            for(int i=0;i<ansx.size();i++)
                printf("%d %d
    ",ansx[i],ansy[i]);
        }
    
        return 0;
    }
  • 相关阅读:
    SYSTEM32 下的几乎所有文件的简单说明
    Windows2000 下管理员账户真的不安全
    Windows2000 下管理员账户真的不安全
    SYSTEM32 下的几乎所有文件的简单说明
    看看你电脑里面有多少垃圾文件浪费内存
    巧妙利用三招保护局域网中的 IP 地址
    Sun推出OpenSolaris 为技术立异注入生机
    高质量C /C编程指南附录B :C /C试题和答案
    高质量C /C编程指南第8章 C 函数的初级特性
    俄罗斯邮政将迁徙到Linux 有关机构已入手入手测试Linux
  • 原文地址:https://www.cnblogs.com/zufezzt/p/6367242.html
Copyright © 2011-2022 走看看