$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-;
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 = ;
while(!isdigit(c)) c = getchar();
while(isdigit(c))
{
x = x * + c - '';
c = getchar();
}
} struct Edge
{
int a,b,nx;
}e[];
int h[];
int n,m,sz,s,t,ds,dt;
int belong[],block;
vector<int>ansx,ansy; struct X
{
int e1,e2;
}w[]; 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!=-;i=e[i].nx)
{
int to=e[i].b;
if(belong[to]!=) 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,-,sizeof h);
for(int i=;i<=m;i++)
{
int a,b; cin>>a>>b;
add(a,b); add(b,a);
}
cin>>s>>t>>ds>>dt; for(int i=;i<=n;i++)
{
if(i==s) continue;
if(i==t) continue;
if(belong[i]!=) continue;
block++; dfs(i);
} for(int i=;i<=block;i++) w[i].e1=w[i].e2=-; for(int i=;i<sz;i=i+)
{
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==-) 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==-) 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==-) 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==-) w[belong[e[i].a]].e2=i;
}
} int sum=; vector<int>tmp;
for(int i=;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()==)
{
ansx.push_back(s);
ansy.push_back(t);
ds--; dt--;
} else
{
ansx.push_back(e[w[tmp[]].e1].a);
ansy.push_back(e[w[tmp[]].e1].b);
ansx.push_back(e[w[tmp[]].e2].a);
ansy.push_back(e[w[tmp[]].e2].b); ds--; dt--; for(int i=;i<tmp.size();i++)
{
if(ds>)
{
ansx.push_back(e[w[tmp[i]].e1].a);
ansy.push_back(e[w[tmp[i]].e1].b);
ds--;
}
else if(dt>)
{
ansx.push_back(e[w[tmp[i]].e2].a);
ansy.push_back(e[w[tmp[i]].e2].b);
dt--;
}
} } if(ds<||dt<||ansx.size()!=n-) printf("No\n");
else
{
printf("Yes\n");
for(int i=;i<ansx.size();i++)
printf("%d %d\n",ansx[i],ansy[i]);
} return ;
}

CodeForces 723F st-Spanning Tree的更多相关文章

  1. codeforces 609E Minimum spanning tree for each edge

    E. Minimum spanning tree for each edge time limit per test 2 seconds memory limit per test 256 megab ...

  2. [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]

    这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...

  3. 【codeforces 723F】st-Spanning Tree

    [题目链接]:http://codeforces.com/contest/723/problem/F [题意] 给你一张图; 让你选择n-1条边; 使得这张图成为一颗树(生成树); 同时s的度数不超过 ...

  4. codeforces 723F : st-Spanning Tree

    Description There are n cities and m two-way roads in Berland, each road connects two cities. It is ...

  5. codeforces 609E. Minimum spanning tree for each edge 树链剖分

    题目链接 给一个n个节点m条边的树, 每条边有权值, 输出m个数, 每个数代表包含这条边的最小生成树的值. 先将最小生成树求出来, 把树边都标记. 然后对标记的边的两个端点, 我们add(u, v), ...

  6. Codeforces 1133 F2. Spanning Tree with One Fixed Degree 并查集+生成树

    好久没更新博客了,一直懒得动,这次更新一下. 题意大概是:给出一个图,求它的一个一号节点的度数恰好为D的生成树的方案. 一开始随便水了个乱搞贪心,不出意外并没有过. 仔细思考之后,对于这个问题我们可以 ...

  7. Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)

    题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上 ...

  8. CodeForces 618D Hamiltonian Spanning Tree

    题意:要把所有的节点都访问一次,并且不能重复访问,有两种方式访问,一种是根据树上的路径 走和当前节点连接的下一个节点cost x, 或者可以不走树上边,直接跳到不与当前节点连接的节点,cost y 分 ...

  9. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge LCA链上最大值

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

  10. Codeforces Educational Codeforces Round 3 E. Minimum spanning tree for each edge 树上倍增

    E. Minimum spanning tree for each edge 题目连接: http://www.codeforces.com/contest/609/problem/E Descrip ...

随机推荐

  1. 【C++ STL】Map和Multimap

    1.结构 Map和multimap将key/value pair(键值/实值 队组)当作元素,进行管理.他们根据key的排序准则将元素排序.multimap允许重复元素,map不允许. 元素要求: k ...

  2. 【BZOJ4903】【CTSC2017】吉夫特 [DP]

    吉夫特 Time Limit: 15 Sec  Memory Limit: 512 MB[Submit][Status][Discuss] Description Input 第一行一个整数n. 接下 ...

  3. bzoj 2083: [Poi2010]Intelligence test——vecto+二分

    Description 霸中智力测试机构的一项工作就是按照一定的规则删除一个序列的数字,得到一个确定的数列.Lyx很渴望成为霸中智力测试机构的主管,但是他在这个工作上做的并不好,俗话说熟能生巧,他打算 ...

  4. 【洛谷 P1525】 关押罪犯 (二分图+二分答案)

    题目链接 并查集+贪心当然是可以做的. 但我用二分图+二分答案. 二分一个\(mid\),删去所有边权小于等于\(mid\)的边,看有没有奇环存在,如果存在,则\(mid\)不行. #include ...

  5. 多重部分和问题 (dp)

    题目描述 有n种不同大小的数字Ai,每种各Mi个.判断是否能从这些数字中选出若干个使它们的和恰好为K. 这个问题可以用DP求解,递推关系式的定义会影响最终的复杂度. 第一种定义: dp[i+1][j] ...

  6. bufferd对象详解

    使用buffer类处理二进制数据 在客户端javascript脚本代码中,对于二进制数据并没有提供一个很好的支持.然后在nodejs中需要处理像TCP流或文件流时,必须要处理二进制数据.因此在node ...

  7. linux启动过程——(三)

  8. Android控件——ToggleButton多状态按钮(实现灯泡的开关)

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAxoAAAFxCAIAAAB7jkm1AAAgAElEQVR4nOy9eXgUVb7/Dy7j3BnH8T

  9. sqlmap参数说明

    --delay 设置每隔几秒测试一次注入 --safe-url 设置sqlmap要访问的正常url --safe-freq 设置每测试多少条注入语句后才去访问safe-url --code 设置能正常 ...

  10. js中的return

    retrun true: 返回正确的处理结果. return false:分会错误的处理结果,终止处理. return:把控制权返回给页面(如果条件满足,后面的逻辑就不执行了). if(this.in ...