您的位置:首页 > 其它

Codeforces Round #375 (Div. 2) F. st-Spanning Tree(给你n个点,m条边,有两个给定的点S,T以及它们在生成树中最大的度数)

2016-10-04 20:19 567 查看
传送门:Codeforces Round #375 (Div. 2) F. st-Spanning Tree

题意:

给你n个点,m条边,有两个给定的点S,T以及它们在生成树中最大的度数

求能否构造出一棵树,使得这两个点的度数满足要求

思路:

求出不使用与S,T有关的边构成的联通块

这些联通块与S,T有三种联通情况

1.只与S相连

2.只与T相连

3.与S和T均相连

记录一下已经使用的边的数量就可以了

#include<bits/stdc++.h>
using namespace std;
const int N=5e5+10;
struct Edge{
int from,to;
}e
;
vector<Edge>tmp,ans,mp
;
int f
,flag
;

int find(int x){
return f[x]==x ? x:f[x]=find(f[x]);
}

int main(){
int n,m,s,t,ds,dt,degree_s=0,degree_t=0;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)   f[i]=i;
for(int i=1;i<=m;i++)
scanf("%d%d",&e[i].from,&e[i].to);
scanf("%d%d%d%d",&s,&t,&ds,&dt);
//构造出与S,T无关的若干个联通块
for(int i=1;i<=m;i++){
if(e[i].from==s||e[i].to==s||e[i].from==t||e[i].to==t)
tmp.push_back(e[i]);
else{
int x=find(e[i].from),y=find(e[i].to);
if(x!=y)    f[x]=y,ans.push_back(e[i]);
}
}
bool Sta=false;//标记是否有S-T这条边
for(int i=0;i<tmp.size();i++){
if(tmp[i].to==s||tmp[i].to==s||tmp[i].to==t||tmp[i].to==t)
swap(tmp[i].from,tmp[i].to);
int x=find(tmp[i].from),y=find(tmp[i].to);
if(x+y==s+t)
Sta=true;
else if(x==s)
flag[y]|=1,mp[y].push_back(tmp[i]);
else if(y==s)
flag[x]|=1,mp[x].push_back(tmp[i]);
else if(x==t)
flag[y]|=2,mp[y].push_back(tmp[i]);
else if(y==t)
flag[x]|=2,mp[x].push_back(tmp[i]);
}
for(int i=1;i<=n;i++){
if(flag[i]==1){ //只与S相连
degree_s++;
ans.push_back(mp[i][0]);
}
else if(flag[i]==2){//只与T相连
degree_t++;
ans.push_back(mp[i][0]);
}
}
bool Flag=false;
for(int i=1;i<=n;i++)
if(flag[i]==3){
if(Flag==false){
int cnt=0;
for(int j=0;j<mp[i].size();j++){
if(mp[i][j].from==s&&(cnt&1)==0)
ans.push_back(mp[i][j]),cnt|=1;
else if(mp[i][j].from==t&&(cnt&2)==0)
ans.push_back(mp[i][j]),cnt|=2;
}
degree_s++,degree_t++;
Flag=true;
}
else{
int st=ds-degree_s < dt-degree_t ? t:s;
for(int j=0;j<mp[i].size();j++)
if(mp[i][j].from==st){
ans.push_back(mp[i][j]);
break;
}
st==t ? ++degree_t:++degree_s;
}
}
if(Flag==false&&Sta){
degree_s++,degree_t++;
ans.push_back((Edge){s,t});
}
if(degree_s<=ds&°ree_t<=dt&&ans.size()==n-1){
printf("Yes\n");
for(int i=0;i<ans.size();i++)
printf("%d %d\n",ans[i].from,ans[i].to);
}
else
printf("No\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐