[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 }
时间: 2024-10-25 08:53:36

[CF723F] st-Spanning Tree的相关文章

CF609E. Minimum spanning tree for each edge

题解:随便构造一颗最小生成树 然后对于其他不在树上的边  考虑到 删除这条链上的最大值在把这条边加上去 能得到这条边所在的最小生成树 可以LCT维护 但是明显这个题是静态的树就没必要LCT 当然我觉得最优的是树剖以后ST nlogn的的复杂度 也可以树剖+线段树nlog^2的复杂度 #include <bits/stdc++.h> const int MAXN=2e5+10; #define ll long long using namespace std; ll read(){ ll x=0

HDU 4896 Minimal Spanning Tree(矩阵快速幂)

题意: 给你一幅这样子生成的图,求最小生成树的边权和. 思路:对于i >= 6的点连回去的5条边,打表知907^53 mod 2333333 = 1,所以x的循环节长度为54,所以9个点为一个循环,接下来的9个点连回去的边都是一样的.预处理出5个点的所有连通状态,总共只有52种,然后对于新增加一个点和前面点的连边状态可以处理出所有状态的转移.然后转移矩阵可以处理出来了,快速幂一下就可以了,对于普通的矩阵乘法是sigma( a(i, k) * b(k, j) ) (1<=k<=N), 现在

【HDU 4408】Minimum Spanning Tree(最小生成树计数)

Problem Description XXX is very interested in algorithm. After learning the Prim algorithm and Kruskal algorithm of minimum spanning tree, XXX finds that there might be multiple solutions. Given an undirected weighted graph with n (1<=n<=100) vertex

BNUOJ 26229 Red/Blue Spanning Tree

Red/Blue Spanning Tree Time Limit: 2000ms Memory Limit: 131072KB This problem will be judged on HDU. Original ID: 426364-bit integer IO format: %I64d      Java class name: Main Given an undirected, unweighted, connected graph, where each edge is colo

HDOJ 题目4408 Minimum Spanning Tree(Kruskal+Matrix_Tree)

Minimum Spanning Tree Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1408    Accepted Submission(s): 450 Problem Description XXX is very interested in algorithm. After learning the Prim algori

Lab - Modify Default Spanning Tree Behavior

Modify Default Spanning Tree Behavior Topology Objective observe what happens when the default spanning tree behavior is modified. Background Four switches have just been installed. The distribution layer switches are Catalyst 3560s, and the access l

Lab - Per-VLAN Spanning Tree Behavior

Per-VLAN Spanning Tree Behavior Topology Objectives: Observe the behavior of a separate spanning tree instance per VLAN. Change spanning tree mode to rapid spanning tree. Background: Four switches have just been installed. The distribution layer swit

Lab - Multiple Spanning Tree

Multiple Spanning Tree Topology Objective Obsrve te behavior of Multiple Spanning Tree(MST) Background Four switches have just been installed. The distribution Layer switches are Catalyst 3660s, and the access layer switches are Catalyst 2960. There

第四届华中区程序设计邀请赛暨武汉大学第十三届校赛 网络预选赛 Problem 1566 - C - Spanning Tree

Description You are given a graph with N nodes and M edges. Then every time you are required to add an additional edge with weight Wi connecting the node Ai and Bi in the graph, and then calculate the sum of the edges' weight of the Minimum Spanning

Geeks : Kruskal’s Minimum Spanning Tree Algorithm 最小生成树

寻找图中最小连通的路径,图如下: 算法步骤: 1. Sort all the edges in non-decreasing order of their weight. 2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If cycle is not formed, include this edge. Else, discard it. 3. Repeat st