【生成树趣题】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 ...
随机推荐
- 【CF1187C】Vasya And Array
题目大意:给定一个长度为 N 的数组,以及 M 个区间,给出的区间有两个性质,性质一是给定区间中的元素单调不减,性质二是给定区间中的元素存在相邻单调减的元素对,求构造一个符合给定区间条件的序列,若不存 ...
- 【CF765E】Tree Folding
题目大意:给定一棵 N 个节点的无根树,边权都是 1,可以把树上父亲相同的两条长度相同的链合并,问最后是否可以合并成一条链,如果可以,输出链的最小长度,否则输出 -1. 题解: 由于我们不知道最后的 ...
- nginx启动、停止、重启
转自https://www.cnblogs.com/wangcp-2014/p/9922845.html 启动 启动代码格式:nginx安装目录地址 -c nginx配置文件地址 例如: [root@ ...
- 使用xpath提取页面所有a标签的href属性值
# -*- coding: utf-8 -*- #1.选取节点 #获取所有的div元素 //div #/代表获取根节点的直接子元素 #获取所有带有id属性的div //div[@id] #2.谓词(索 ...
- buuctf@pwn1_sctf_2016
from pwn import * sh=remote('pwn.buuoj.cn',20086) get_flag=0x08048F0D payload='I'*0x14+'a'*4+p32(get ...
- 修改 mvc webapi 默认返回 json 格式
web api 默认的已 xml 格式返回数据 现在开发一般都是以 json 格式为主 下面配置让 webapi 默认返回 json ,在需要返回 xml 时只需要加一个查询参数 datatype=x ...
- TTTTTTTTTTTTTTTTT POJ 2226 草地覆木板 二分匹配 建图
Muddy Fields Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9754 Accepted: 3618 Desc ...
- k8s节点NotReady问题处理
我把三台虚拟机重启,发现2个节点一直处于NotReady状态,便去查找问题,到最后是因为子节点的kubelet的状态异常了,restart一下就好了,下面转一下解决的思路 昨天晚上,针对K8S环境做了 ...
- stat:查看文件时间参数
Linux 系统中,每个文件主要拥有 3 个时间参数,分别是文件的访问时间.数据修改时间以及状态修改时间: 访问时间(Access Time,简称 atime):只要文件的内容被读取,访问时间就会更新 ...
- R_Studio(关联)对dvdtrans.csv数据进行关联规则分析
dvdtrans.csv数据:该原始数据仅仅包含了两个字段(ID, Item) 用户ID,商品名称(共30条) #导入arules包 #install.packages("arules&qu ...