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-;
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的更多相关文章
- 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 ...
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- 【codeforces 723F】st-Spanning Tree
[题目链接]:http://codeforces.com/contest/723/problem/F [题意] 给你一张图; 让你选择n-1条边; 使得这张图成为一颗树(生成树); 同时s的度数不超过 ...
- codeforces 723F : st-Spanning Tree
Description There are n cities and m two-way roads in Berland, each road connects two cities. It is ...
- codeforces 609E. Minimum spanning tree for each edge 树链剖分
题目链接 给一个n个节点m条边的树, 每条边有权值, 输出m个数, 每个数代表包含这条边的最小生成树的值. 先将最小生成树求出来, 把树边都标记. 然后对标记的边的两个端点, 我们add(u, v), ...
- Codeforces 1133 F2. Spanning Tree with One Fixed Degree 并查集+生成树
好久没更新博客了,一直懒得动,这次更新一下. 题意大概是:给出一个图,求它的一个一号节点的度数恰好为D的生成树的方案. 一开始随便水了个乱搞贪心,不出意外并没有过. 仔细思考之后,对于这个问题我们可以 ...
- Codeforces 618D Hamiltonian Spanning Tree(树的最小路径覆盖)
题意:给出一张完全图,所有的边的边权都是 y,现在给出图的一个生成树,将生成树上的边的边权改为 x,求一条距离最短的哈密顿路径. 先考虑x>=y的情况,那么应该尽量不走生成树上的边,如果生成树上 ...
- CodeForces 618D Hamiltonian Spanning Tree
题意:要把所有的节点都访问一次,并且不能重复访问,有两种方式访问,一种是根据树上的路径 走和当前节点连接的下一个节点cost x, 或者可以不走树上边,直接跳到不与当前节点连接的节点,cost y 分 ...
- 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 ...
- 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 ...
随机推荐
- 9.python爬虫--pyspider
pyspider简介 PySpider:一个国人编写的强大的网络爬虫系统并带有强大的WebUI.采用Python语言编写,分布式架构,支持多种数据库后端,强大的WebUI支持脚本编辑器,任务监视器,项 ...
- 洛谷 P1044 栈
题目背景 栈是计算机中经典的数据结构,简单的说,栈就是限制在一端进行插入删除操作的线性表. 栈有两种最重要的操作,即pop(从栈顶弹出一个元素)和push(将一个元素进栈). 栈的重要性不言自明,任何 ...
- hdu 3948 The Number of Palindromes
The Number of Palindromes Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 262144/262144 K (J ...
- 其他:OI竞赛中的文件操作
本文介绍三种方法进行文件输入输出,都非常实用 第一种方法是采用重定向的形式进行输入输出,很方便 freopen("input.txt","r",stdin); ...
- linux sh脚本异常:/bin/sh^M:bad interpreter: No such file or directory
在Linux中执行.sh脚本,异常/bin/sh^M: bad interpreter: No such file or directory.这是不同系统编码格式引起的:在windows系统中编辑的. ...
- 希尔排序Shell sort
希尔排序Shell Sort是基于插入排序的一种改进,同样分成两部分, 第一部分,希尔排序介绍 第二部分,如何选取关键字,选取关键字是希尔排序的关键 第一块希尔排序介绍 准备待排数组[6 2 4 1 ...
- idea 修改静态资源不需要重启的办法
快捷键Ctrl + Alt + S打开设置面板,勾选Build project automatically选项: 快捷键Ctrl + Shift + A查找registry命令: 在查找到的regis ...
- 关于C++的宏:WIN32和DEBUG
判断平台相关,判断程序是属于debug版本还是release版本,我们会这么做. #ifdef WIN32 #else #endif #ifdef DEBUG // 如果是调试版本 #else //发 ...
- 老生常谈-Activity(山东数漫江湖)
对于activity的七个声生命周期回调,总是被大家翻来覆去的说,甚至说的都有些厌烦了,这部分知识虽然基础但也很重要,谁都不想在面试的时候只说出个一知半解,下面的分析是对阅读<安卓开发艺术探索& ...
- 计蒜客 Goldbach Miller_Rabin判别法(大素数判别法)
题目链接:https://nanti.jisuanke.com/t/25985 题目: Description: Goldbach's conjecture is one of the oldest ...