[CF723F] st-Spanning Tree

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF723F] st-Spanning Tree相关的知识,希望对你有一定的参考价值。

题意:给一个图,求一棵生成树满足点$s$的度数$\\leq d_s$且点$t$的度数$\\leq d_t$

我们观察一下样例

技术分享

如果我们把与$s,t$相连的边删掉

技术分享

可以看出,$(1,2,3)$与$s,t$都有边相连,而$(5,7)$只与$t$有边相连

我们只需分别求出每块的任意一棵生成树,然后连接$6$和$(1,2,3)$,连接$(1,2,3)$和$4$,连接$4$和$(5,7)$即可

于是我们有这样的算法:对于被分割出来的每一块求出任意一棵生成树,最后把它们通过$s$和$t$连起来

分割出来的块有两种:第一种只与$s$或$t$相连,这种块必须连接到对应的$s$或$t$

第二种与$s$和$t$都相连,这种块中只有一个块能同时连接$s$和$t$,其他的只能连接$s,t$中的某一个,对于这种块我们贪心地连接即可

注意特判是否有一条边连接$s$和$t$,如果有,并且没有第二种块,则这条边一定要连,否则一定不连

不难,但是算是锻炼代码能力的题吧我太弱了

 

  1 #include<stdio.h>
  2 struct edgex{
  3     int x,y;
  4 }ex[400010],ans[200010];
  5 struct edge{
  6     int to,nex;
  7 }e[800010];
  8 int h[200010],col[200010],fa[200010],n,tot,s,t,ds,dt,cnt,cstp;
  9 bool st[200010],v[200010],done[200010],cst,mpst;
 10 void add(int a,int b){
 11     tot++;
 12     e[tot].to=b;
 13     e[tot].nex=h[a];
 14     h[a]=tot;
 15 }
 16 void dfs1(int f,int x){
 17     col[x]=f;
 18     v[x]=1;
 19     for(int i=h[x];i;i=e[i].nex){
 20         if(e[i].to!=t&&e[i].to!=s&&col[e[i].to]==0)dfs1(f,e[i].to);
 21     }
 22 }
 23 void dfs2(int f,int x){
 24     col[x]=f;
 25     for(int i=h[x];i;i=e[i].nex){
 26         if(e[i].to!=t&&e[i].to!=s&&col[e[i].to]==0)dfs2(f,e[i].to);
 27     }
 28 }
 29 void calc(int x){
 30     done[x]=1;
 31     fa[x]=s;
 32     for(int i=h[x];i;i=e[i].nex){
 33         if(fa[e[i].to]!=s){
 34             cnt++;
 35             ans[cnt].x=x;
 36             ans[cnt].y=e[i].to;
 37             calc(e[i].to);
 38         }
 39     }
 40 }
 41 int getfa(int x){
 42     return(x==fa[x])?x:fa[x]=getfa(fa[x]);
 43 }
 44 int main(){
 45     int m,i,a;
 46     scanf("%d%d",&n,&m);
 47     for(i=1;i<=m;i++)scanf("%d%d",&ex[i].x,&ex[i].y);
 48     scanf("%d%d%d%d",&s,&t,&ds,&dt);
 49     for(i=1;i<=m;i++){
 50         if((ex[i].x==s&&ex[i].y==t)||(ex[i].x==t&&ex[i].y==s)){
 51             cstp=i;
 52             cst=1;
 53             break;
 54         }
 55     }
 56     for(i=1;i<=m;i++){
 57         if(i!=cstp){
 58             add(ex[i].x,ex[i].y);
 59             add(ex[i].y,ex[i].x);
 60         }
 61     }
 62     for(i=h[s];i;i=e[i].nex){
 63         if(col[e[i].to]==0)dfs1(e[i].to,e[i].to);
 64     }
 65     for(i=h[t];i;i=e[i].nex){
 66         if(col[e[i].to]==0)
 67             dfs2(e[i].to,e[i].to);
 68         else if(v[e[i].to]){
 69             st[col[e[i].to]]=1;
 70             mpst=1;
 71         }
 72     }
 73     for(i=1;i<=n;i++)fa[i]=i;
 74     fa[t]=s;
 75     for(i=h[s];i;i=e[i].nex){
 76         if(!st[col[e[i].to]]&&!done[e[i].to]){
 77             cnt++;
 78             ans[cnt].x=s;
 79             ans[cnt].y=e[i].to;
 80             ds--;
 81             calc(e[i].to);
 82         }
 83     }
 84     for(i=h[t];i;i=e[i].nex){
 85         if(!st[col[e[i].to]]&&!done[e[i].to]){
 86             cnt++;
 87             ans[cnt].x=t;
 88             ans[cnt].y=e[i].to;
 89             dt--;
 90             calc(e[i].to);
 91         }
 92     }
 93     if(cst&&!mpst){
 94         cnt++;
 95         ans[cnt].x=s;
 96         ans[cnt].y=t;
 97         ds--;
 98         dt--;
 99     }else{
100         for(i=h[t];i;i=e[i].nex){
101             if(st[col[e[i].to]]){
102                 cnt++;
103                 ans[cnt].x=s;
104                 ans[cnt].y=col[e[i].to];
105                 ds--;
106                 cnt++;
107                 ans[cnt].x=t;
108                 ans[cnt].y=e[i].to;
109                 dt--;
110                 calc(col[e[i].to]);
111                 break;
112             }
113         }
114     }
115     if(dt<0||ds<0){
116         puts("No");
117         return 0;
118     }
119     i=h[s];
120     while(i&&ds>0){
121         a=getfa(e[i].to);
122         if(a!=s){
123             fa[a]=s;
124             cnt++;
125             ans[cnt].x=s;
126             ans[cnt].y=e[i].to;
127             ds--;
128             calc(e[i].to);
129         }
130         i=e[i].nex;
131     }
132     i=h[t];
133     while(i&&dt>0){
134         a=getfa(e[i].to);
135         if(a!=s){
136             fa[a]=s;
137             cnt++;
138             ans[cnt].x=t;
139             ans[cnt].y=e[i].to;
140             dt--;
141             calc(e[i].to);
142         }
143         i=e[i].nex;
144     }
145     for(i=1;i<=n;i++)getfa(i);
146     for(i=1;i<=n;i++){
147         if(fa[i]!=s){
148             puts("No");
149             return 0;
150         }
151     }
152     puts("Yes");
153     for(i=1;i<n;i++)printf("%d %d\\n",ans[i].x,ans[i].y);
154 }

以上是关于[CF723F] st-Spanning Tree的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 723F st-Spanning Tree

[CF468D]Tree

[CF468D] Tree

CF431C k-Tree dp

CF 1039D You Are Given a Tree && CF1059E Split the Tree 的贪心解法

树链剖分CF343DWater Tree