Cddeforces 723F - st-Spanning Tree(构造,无权生成树)

来源:互联网 发布:天猫运营数据分析表格 编辑:程序博客网 时间:2024/06/06 05:56

题目:http://codeforces.com/contest/723/problem/F
题意:

给你一个联通无向图
让你构造一个无权生成树,使得——
S点的度数不超过SD
T点的度数不超过TD

分析:

这题和上一题一样都是构造(灵机一动~~)
首先把不包含s和t的边先求一下连通块
处理完后还剩三种边
s-某个连通块 t-某个连通块 s-t
然后对于某个连通块只与s有边,那么连接,t同理
如果某个既可以和s连也可以和t连,那么就分别和s,t连来保持连通
最后连s-t的边
如果到最后图都不连通或者s和t的度不满足,那么无解
否则有解

代码:

#include <bits/stdc++.h>using namespace std;const int MAX=4e5+9;int a[MAX],b[MAX],s,t,ds,dt,n,m,fa[MAX];bool ms[MAX],mt[MAX];vector<int> vs,vt;vector<pair<int,int> > ans;int findfa(int x){return fa[x]==x?x:fa[x]=findfa(fa[x]);}void merge(int a,int b) {    if (a==s) ds--;    if (a==t) dt--;    fa[findfa(a)]=findfa(b),ans.push_back(make_pair(a,b));}int main() {    ios_base::sync_with_stdio(false),cin.tie(0),cout.tie(0);    cin>>n>>m;    for (int i=1; i<=n; i++) fa[i]=i;    for (int i=1; i<=m; i++) cin>>a[i]>>b[i];    cin>>s>>t>>ds>>dt;    for (int i=1; i<=m; i++)        if (a[i]!=s && a[i]!=t && b[i]!=s && b[i]!=t) {            if (findfa(a[i])!=findfa(b[i]))                merge(a[i],b[i]);        } else {            if (a[i]==s) vs.push_back(b[i]);            if (b[i]==s) vs.push_back(a[i]);            if (a[i]==t) vt.push_back(b[i]);            if (b[i]==t) vt.push_back(a[i]);        }    for (int i=0; i<vs.size(); i++) ms[findfa(vs[i])]=1;    mt[t]=1,ms[s]=1;    for (int i=0; i<vt.size(); i++) {        int x=vt[i];        mt[findfa(x)]=1;        if (!ms[findfa(x)] && findfa(x)!=findfa(t))            merge(x,t),dt--;    }    for (int i=0; i<vs.size(); i++) {        int x=vs[i];        if (!mt[findfa(x)] && findfa(x)!=findfa(s))            merge(x,s),ds--;    }    for (int i=0; i<vs.size(); i++) {        int x=vs[i];        if (findfa(x)!=findfa(s) && findfa(x)!=findfa(t) && ds)            merge(x,s),ds--;    }    for (int i=0; i<vt.size(); i++) {        int x=vt[i];        if (findfa(x)!=findfa(s) && findfa(x)!=findfa(t))            merge(x,t),dt--;    }    for (int i=0; i<vs.size(); i++) {        int x=vs[i];        if (x==t && !dt) ;        else if (findfa(x)!=findfa(s) && ds)            merge(x,s),ds--;    }    for (int i=0; i<vt.size(); i++) {        int x=vt[i];        if (x==s && !ds) ;        else if (findfa(x)!=findfa(t))            merge(x,t),dt--;    }    bool flg=0;    for (int i=2; i<=n; i++) if (findfa(i)!=findfa(1)) flg=1;    if (dt<0 || ds<0 || flg) return cout<<"No\n",0;    cout<<"Yes\n";    for (int i=0; i<ans.size(); i++) cout<<ans[i].first<<" "<<ans[i].second<<'\n';}
0 0