Codeforces Round #375 (Div. 2)F. st-Spanning Tree
题目链接:F. st-Spanning Tree
题解:先把与s,t无关的边遍历一次,把能够链接两个不同的并查集连起来,然后在把每个块标记一下看能否与s,t相连,如果有一个块s和t都可以连就先把s,t联通,然后把只能与s和只能t相连的块分别与s,t相连
连的过程中维护ds,dt,最后在贪心把两个都可以连的连上去.最后看连的边数是否有n-1条,有的话就yes输出答案
1 By lhclqslove, contest: Codeforces Round #375 (Div. 2), problem: (F) st-Spanning Tree, Accepted, # 2 #include<bits/stdc++.h> 3 #include<set> 4 #include<cstdio> 5 #include<iomanip> 6 #include<iostream> 7 #include<string> 8 #include<cstring> 9 #include<algorithm> 10 #define pb push_back 11 #define ll long long 12 #define fi first 13 #define se second 14 #define PI 3.14159265 15 #define ls l,m,rt<<1 16 #define rs m+1,r,rt<<1|1 17 #define eps 1e-7 18 #define pii pair<int,int> 19 typedef unsigned long long ull; 20 const int mod=1e3+5; 21 const ll inf=0x3f3f3f3f3f3f3f; 22 const int maxn=2e5+5; 23 using namespace std; 24 int n,m,f[maxn],x[maxn*2],y[maxn*2],link1[maxn],link2[maxn]; 25 vector<pii>edge; 26 set<int>yu; 27 bool vis[maxn]; 28 vector<pii>ans; 29 set<int>ss,tt; 30 void init() 31 { 32 for(int i=0;i<maxn;i++)f[i]=i; 33 } 34 int find(int x) 35 { 36 if(f[x]==x)return x; 37 else return f[x]=find(f[x]); 38 } 39 void link(int x,int y) 40 { 41 int fx=find(x); 42 int fy=find(y); 43 f[fy]=fx; 44 } 45 int main() 46 { 47 ios::sync_with_stdio(false); 48 cin.tie(0);cout.tie(0); 49 cin>>n>>m; 50 init(); 51 for(int i=0;i<m;i++) 52 { 53 cin>>x[i]>>y[i]; 54 } 55 int s,t,ds,dt; 56 cin>>s>>t>>ds>>dt; 57 if(m<n-1) 58 { 59 cout<<"No"<<endl;return 0; 60 } 61 for(int i=0;i<m;i++) 62 { 63 if(x[i]!=s&&x[i]!=t&&y[i]!=t&&y[i]!=s) 64 { 65 edge.pb({x[i],y[i]}); 66 } 67 else 68 { 69 if(x[i]==s)ss.insert(y[i]); 70 if(y[i]==s)ss.insert(x[i]); 71 if(x[i]==t)tt.insert(y[i]); 72 if(y[i]==t)tt.insert(x[i]); 73 } 74 } 75 for(int i=0;i<edge.size();i++) 76 { 77 if(find(edge[i].fi)!=find(edge[i].se)) 78 { 79 ans.pb(edge[i]); 80 link(edge[i].se,edge[i].fi); 81 } 82 } 83 for(int to:tt) 84 { 85 int fto=find(to); 86 link1[fto]=1; 87 } 88 for(int to:ss) 89 { 90 int fto=find(to); 91 link2[fto]=1; 92 }bool flag=false; 93 if(!flag)//st相连 94 { 95 for(int to:tt) 96 { 97 if(to==s)continue; 98 int fto=find(to); 99 if(link2[fto]) 100 {//cout<<to<<"UUU"<<t<<endl; 101 if(dt){ans.pb({t,to});dt--;link(to,t);vis[find(to)]=1;break;} 102 } 103 } 104 for(int to:ss) 105 { 106 if(to==t)continue; 107 if(vis[find(to)]) 108 { 109 //cout<<to<<"SSS"<<s<<endl; 110 if(ds)ans.pb({s,to}),ds--,link(to,s); 111 flag=true; 112 break; 113 } 114 } 115 } 116 // cout<<ds<<" "<<dt<<endl; 117 for(int to:tt)//只与t相连 118 { 119 if(to==s)continue; 120 int fto=find(to); 121 if(!link2[fto]&&fto!=find(t)) 122 { 123 // cout<<"####"<<endl; 124 if(dt)ans.pb({to,t}),dt--,link(to,t); 125 else 126 { 127 cout<<"No"<<endl;return 0; 128 } 129 } 130 } 131 for(int to:ss)//只与s相连 132 { 133 if(to==t)continue; 134 int fto=find(to); 135 if(!link1[fto]&&fto!=find(s)) 136 { 137 // cout<<"$$$$"<<endl; 138 if(ds)ans.pb({to,s}),ds--,link(s,to); 139 else 140 { 141 cout<<"No"<<endl;return 0; 142 } 143 } 144 } 145 for(int to:ss)//个都相连 146 { 147 if(to==t)continue; 148 int fto=find(to); 149 if(fto!=find(s)) 150 { 151 if(ds) 152 { 153 ans.pb({to,s});ds--,link(s,to); 154 } 155 } 156 } 157 for(int to:tt) 158 { 159 if(to==s)continue; 160 int fto=find(to); 161 if(fto!=find(t)) 162 { 163 if(dt) 164 { 165 ans.pb({to,t});dt--,link(to,t); 166 } 167 } 168 } 169 if(find(s)!=find(t)) 170 { 171 if(ds&&dt&&ss.count(t)) 172 { 173 ans.pb({s,t});ds--;dt--; 174 } 175 else 176 { 177 cout<<"No"<<endl;return 0; 178 } 179 } 180 if(ans.size()==n-1) 181 { 182 cout<<"Yes"<<endl; 183 for(pii tmp :ans) 184 { 185 cout<<tmp.fi<<" "<<tmp.se<<endl; 186 } 187 } 188 else 189 { 190 cout<<"No"<<endl; 191 } 192 return 0; 193 }