题意:给一个图,求一棵生成树满足点$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 }
时间: 2024-10-25 08:53:36