CodeForces 723F【DFS瞎搞】
题意:
给你一幅图,你要用这些边构造一个树,
s和t两个节点的度数不能超过ds dt
s和t两个节点的度数不能超过ds dt
而且图是保证没有环
思路:
树的性质是:无环(已经保证),无向(保证),连通(还要判断)
首先把S,T点从图里剥离出来,就是把除S和T点搞成几个连通块
对于这些连通块有三种:只与S连的,只与T连的,还有一种是两个都连的,
然后就是要把S和T与那些连通块相连,保证连通。
由于对于S和T相连的点并不是连通块的老大,而且S和T连出去的点还可能同时在一个连通块里;
所以预处理一下S和T连接点的老大,塞到set里去去个重,连一个子节点或者就是他本身就好了;
中间还要判断S和T的连通性,最后再判断一下度数就好啦
PS:主要是要知道树的性质,还有就是要知道树的哪些边是一定要连的;
好菜啊!!!
#include <bits/stdc++.h> using namespace std; const int N=2e5+10; vector<int>ma[N]; vector<int>ans[N],tt[N],ss[N]; set<int>s; set<int>t; int num[N]; int S,T; int pre[N]; void dfs(int x,int k) { pre[x]=k; for(int i=0;i<ma[x].size();i++) { //printf("%d\n",ma[x][i]); if(ma[x][i]==S||ma[x][i]==T||pre[ma[x][i]]) continue; ans[x].push_back(ma[x][i]); dfs(ma[x][i],k); } } int main() { int n,m; int x,y; int ds,dt; int ps,pt; scanf("%d%d",&n,&m); while(m--) { scanf("%d%d",&x,&y); ma[x].push_back(y); ma[y].push_back(x); } scanf("%d%d%d%d",&S,&T,&ds,&dt); //首先剥离与s和t连通的东东; memset(pre,0,sizeof(pre)); for(int i=1;i<=n;i++) { if(i==S||i==T||pre[i]) continue; dfs(i,i); } //然后就是从s的一些连通块,或者从t出发的一些连通块 int flag=0; ps=pt=0; memset(num,0,sizeof(num)); //建下边,去个重; for(int i=0;i<ma[S].size();i++) { if(ma[S][i]==T) { flag++; continue; } s.insert(pre[ma[S][i]]); ss[pre[ma[S][i]]].push_back(ma[S][i]); } for(int i=0;i<ma[T].size();i++) { if(ma[T][i]==S) continue; t.insert(pre[ma[T][i]]); tt[pre[ma[T][i]]].push_back(ma[T][i]); } set<int>::iterator it; for(it=s.begin();it!=s.end();it++) num[*it]++; for(it=t.begin();it!=t.end();it++) { num[*it]++; if(num[*it]==1) { ans[T].push_back(tt[*it][0]); num[*it]=0; pt++; } } for(it=s.begin();it!=s.end();it++) { if(num[*it]==1) { ans[S].push_back(ss[*it][0]); num[*it]=0; ps++; } } int ff=0; for(it=s.begin();it!=s.end();it++) { if(num[*it]>1) { if(!ff) { ans[S].push_back(ss[*it][0]); ans[T].push_back(tt[*it][0]); ps++; pt++; ff=1; continue; } if(ps<ds) { ans[S].push_back(ss[*it][0]); ps++; } else//不行的话只能给T啊!!!; { ans[T].push_back(tt[*it][0]); pt++; } } } if(!ff)//如果不能搞在一起的话 { if(flag)//判断是否本来就在一起 { ans[S].push_back(T); ps++; pt++; } else { puts("NO"); return 0; } } if(ps>ds||pt>dt) puts("No"); else { puts("Yes"); for(int i=1;i<=n;i++) { for(int j=0;j<ans[i].size();j++) { printf("%d %d\n",i,ans[i][j]); } } } return 0; }