[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
CF 1039D You Are Given a Tree && CF1059E Split the Tree 的贪心解法