【生成树趣题】CF723F st-Spanning Tree
题意:
给定一个n个点m条边的无向联通图,没有重边和自环。给定s和t,求一棵生成树,使得s,t的度数不超过ds,dt。若有解,输出“Yes”和方案(多组方案输出任意一组),若无解,输出“No”。
数据范围:
2 ≤ n ≤ 200 000
分析:
首先,可以把边分成两类:一类是端点含s或t的,另一类是和s,t没有任何关系的。第二类边可以随便乱连,而第一类边不可以。
所以,就先把第二类边乱连,随便连,反正没有边权连就是了,用一个并查集,相当于搞一个生成树森林出来,这样我们就有了很多很多块集合(相当于被缩成一个点,要注意细节)和s,t两个点。
集合中只与s,t的其中一个点有边的,只能连那个边,否则就不联通了。一边连一边判断s,t的度数,如果超过了就判定无解。
集合中和s,t都有边相连的,选一个和s,t都连一条边,这样可以使s,t联通的同时尽量最小化度数。(s,t直接相连,度数各增加1,某一个集合再和s,t中的一个相连,s,t中的一个度数会增加1)
剩下的和s,t都有边相连的集合,随便连s,t都可以。(如果一个点的度数被连完了,就连另外那个)
最后,如果没有和s,t都有边相连的集合,那么此时s,t还没有被连起来,那么还要在s,t之间直接连一条边。
注意还要判断它是不是一棵生成树的形态(边数为n-1)
#include<cstdio>
#include<iostream>
#include<iomanip>
#include<algorithm>
#include<vector>
#include<queue>
using namespace std;
#define ll long long
#define N 200005
int n,m,s,t,ds,dt;
vector<int>G[N];
vector<pair<int,int> >ans;
int f[N];//并查集
int ls[N],lt[N];//编号为i的集合通过ls[i]/lt[i]和s/t相连
inline int rd()
{
int f=,x=;char c=getchar();
while(c<''||''<c){if(c=='-')f=-f;c=getchar();}
while(''<=c&&c<='') x=(x<<)+(x<<)+(c^),c=getchar();
return f*x;
}
int Find(int x)
{
if(f[x]==x) return x;
return f[x]=Find(f[x]);
}
bool Union(int u,int v)
{
int x=Find(u),y=Find(v);
if(x==y) return false;
if(x<y) f[y]=x;
else f[x]=y;
return true;
}
void Init()
{
for(int i=;i<=n;i++)
f[i]=i;
}
int main()
{
n=rd(),m=rd();
for(int i=;i<=m;i++)
{
int u=rd(),v=rd();
G[u].push_back(v);
G[v].push_back(u);
}
s=rd(),t=rd(),ds=rd(),dt=rd();
Init();
//乱连不含s,t的边
for(int u=;u<=n;u++)
{
if(u==s||u==t) continue;
for(int i=;i<G[u].size();i++)
{
int v=G[u][i];
if(v==s||v==t) continue;
if(Union(u,v)) ans.push_back(make_pair(u,v));
}
}
//处理集合的哪些边和s,t相连的情况
for(int i=;i<G[s].size();i++)
if(G[s][i]!=t)
{
int x=Find(G[s][i]);
ls[x]=G[s][i];
}
for(int i=;i<G[t].size();i++)
if(G[t][i]!=s)
{
int x=Find(G[t][i]);
lt[x]=G[t][i];
}
//处理只和s,t中的一个相连的集合
for(int i=;i<=n;i++)
{
if(ls[i]&&!lt[i])
{
ds--;
Union(s,i);
ans.push_back(make_pair(s,ls[i]));
}
else if(!ls[i]&<[i])
{
dt--;
Union(t,i);
ans.push_back(make_pair(t,lt[i]));
}
if(ds<||dt<)
{
puts("No");
return ;
}
}
//处理和s,t都相连的集合 第一个会和s,t都连 s,t连通之后就只会连一个
for(int i=;i<=n;i++)
if(ls[i]&<[i])
{
if(ds&&Union(s,i))
{/*短路运算符 Union不能写在前面 或者也可以用find()判断 Union写在里面*/
ds--;
ans.push_back(make_pair(s,ls[i]));
}
if(dt&&Union(t,i))
{
dt--;
ans.push_back(make_pair(t,lt[i]));
}
if(Find(s)!=Find(i)||Find(t)!=Find(i)) //说明前面没有办法连 度数都用完了
{
puts("No");
return ;
}
}
if(Find(s)!=Find(t))//s,t还没有连通
{
bool f=;
for(int i=;i<G[s].size();i++)
if(G[s][i]==t)
{
f=;
break;
}
if(ds&&dt&&f)
ans.push_back(make_pair(s,t));
if(!f)
{
puts("No");
return ;
}
}
if(ans.size()!=n-)
{//满足是一棵生成树
puts("No");
return ;
}
puts("Yes");
for(int i=;i<ans.size();i++)
printf("%d %d\n",ans[i].first,ans[i].second);
return ;
}
Code
【生成树趣题】CF723F st-Spanning Tree的更多相关文章
- AtCoder Regular Contest 093 E: Bichrome Spanning Tree(生成树)
Bichrome Spanning Tree 题意: 给出一个n个点,m条边的无向连通图,现在要给每条边染色,可以染成黑色或者白色. 现在要求在染色完毕后,找出一个至少包含一条黑边和一条白边的最小生成 ...
- 【HDU 4408】Minimum Spanning Tree(最小生成树计数)
Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Krusk ...
- 数据结构与算法分析–Minimum Spanning Tree(最小生成树)
给定一个无向图,如果他的某个子图中,任意两个顶点都能互相连通并且是一棵树,那么这棵树就叫做生成树(spanning tree). 如果边上有权值,那么使得边权和最小的生成树叫做最小生成树(MST,Mi ...
- CF# Educational Codeforces Round 3 E. 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 ...
- HDU 4408 Minimum Spanning Tree 最小生成树计数
Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Ot ...
- STP(Spanning Tree Protocol)
STP生成树协议 问题 为了提高网络的可用性,需要进行冗余和备份.但是冗余路径会产生环路 环路会导致以下问题 广播风暴:由于交换机会对广播.多播.和未知目标MAC的单播包进行泛洪,在存在环路的情况 ...
- [Educational Round 3][Codeforces 609E. Minimum spanning tree for each edge]
这题本来是想放在educational round 3的题解里的,但觉得很有意思就单独拿出来写了 题目链接:609E - Minimum spanning tree for each edge 题目大 ...
- [BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树
[BZOJ3080]Minimum Variance Spanning Tree/[BZOJ3754]Tree之最小方差树 题目大意: 给定一个\(n(n\le50)\)个点,\(m(m\le1000 ...
- Educational Codeforces Round 3 E. 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 ...
随机推荐
- JAVA笔记11-Final关键字
相当于C++中的const (1)final的变量值(成员变量.局部变量(形参))不可被改变: (2)final的方法不能被重写: (3)final的类不能被继承.
- SpringBoot项目构建、测试、热部署、配置原理、执行流程
SpringBoot项目构建.测试.热部署.配置原理.执行流程 一.项目构建 二.测试和热部署 三.配置原理 四.执行流程
- css,scss解决样式:表格的重叠边框
初始效果: 解决方法: 给带有边框的元素设置如下样式margin:0 0 -borderwidth -borderwidth 这里的borderwidth即为边框的宽度,按照上图所示,则添加样式 ma ...
- jquery delegate()方法 语法
jquery delegate()方法 语法 作用:delegate() 方法为指定的元素(属于被选元素的子元素)添加一个或多个事件处理程序,并规定当这些事件发生时运行的函数.使用 delegate( ...
- Linux—查看路由
下面那些命令可以用来查看Linux主机的默认路由() A.route B.ifconfig C.ping D.netstat 分析: A.route命令用来显示目前本机路由表的内容,并且还可以针对路由 ...
- luoguP1468 派对灯 Party Lamps x
P1468 派对灯 Party Lamps 题目描述 在IOI98的节日宴会上,我们有N(10<=N<=100)盏彩色灯,他们分别从1到N被标上号码. 这些灯都连接到四个按钮: 按钮1:当 ...
- 理解ext文件系统
理解ext文件系统 @(0001学习博客) 注意:本文参考骏马金龙的博客,详情请移步浏览 一.一些常见的文件系统 Linux的文件系统: ext2(无日志功能), ext3, ext4, xfs, r ...
- tomcat 散点杂记
tomcat有很多细碎的知识点和一些坑点,我将再次记录 域名直指项目 我们经常访问项目都要带上项目目录 eg: http://xwiki.test.com/xwiki or http://jenkin ...
- 四图3d旋转轮播
<!DOCTYPE html><html><head><meta charset="utf-8" /><title>3d ...
- jar 在windows 启动服务,卸载服务,停止端口
参考:https://www.cnblogs.com/zhuchunlei/p/9469569.html 1,启动服务 install.bat @echo off SET JAVA_HOME=&qu ...