• Codeforces Round #544 (Div. 3) F2. Spanning Tree with One Fixed Degree


    题意:给一张图,求一颗生成树,使1号点度数恰为D

    边分成三类,必选的边,1号点上可选的边,其他边

    必选边先连上,1点剩下的边随意连直到度数为D,其他边补全生成树

    必选边怎么求?比赛时用了tarjan求桥(疯狂WA37),因为一些不是桥的结构也会有(任选的)必选边,比如三角形

    所以遍历和1点相连的边,dfs求出通过该边能到达的边,即选了该边以后这些边都是任选了

    这样就对了

    /*
     * Author	: GhostCai
     * Expecto Patronum
    */
    #include<bits/stdc++.h>
    
    using namespace std;
    
    void debug_out() { cerr << endl; }
    template <typename Head, typename... Tail>
    void debug_out(Head H, Tail... T) {
        cerr << " " << H;
        debug_out(T...);
    }
    #define debug(...) 
        cerr << __LINE__ << " [" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
    #define dump(x) cerr << __LINE__ << " " << #x << " = " << (x) << endl
    #define rep(x,y,z) for(int x=y;x<=z;x++)
    #define eep(x,y) for(int x=head[y];x;x=e[x].next)
    inline void shit() {puts("NO");}
    inline void good() {puts("YES");}
    inline int rd(){
    	int ret=0,f=1;char c;
    	while(c=getchar(),!isdigit(c))f=c=='-'?-1:1;
    	while(isdigit(c))ret=ret*10+c-'0',c=getchar();
    	return ret*f;
    }
    #define pc putchar
    #define space() pc(' ')
    #define nextline() pc('
    ')
    void pot(int x){if(!x)return;pot(x/10);pc('0'+x%10);}
    void out(int x){if(!x)pc('0');if(x<0)pc('-'),x=-x;pot(x);}
    
    const int MAXN = 400005;
    
    int n,m,D;
    
    struct Edge{
    	int next,to;
    }e[MAXN<<1];
    int ecnt=1,head[MAXN];
    inline void add(int x,int y){
    	e[++ecnt]={head[x],y};
    	head[x]=ecnt;	
    }
    bool vis[MAXN<<1];
    //pair<pair<int,int>,int> edg[MAXN],tot;
    
    int ind[MAXN];
    
    int fa[MAXN];
    int fnd(int x){return x==fa[x]?x:fa[x]=fnd(fa[x]);}
    void cat(int x,int y){x=fnd(x);y=fnd(y);fa[x]=y;}
    
    int ans[MAXN][2],anscnt;
    void pushans(int x,int y){
    	ans[++anscnt][0]=x;
    	ans[anscnt][1]=y;	
    }
    
    //int dfn[MAXN],low[MAXN],dcnt;
    //int cut[MAXN];
    //
    //void tarjan(int u,int fa){
    //    dfn[u]=low[u]=++dcnt;
    //    for(int i=head[u];i;i=e[i].next){
    //    	int v=e[i].to;
    //        if(!dfn[v]){
    //            tarjan(v,u);
    //            low[u]=min(low[u],low[v]);
    //            if(low[v]>dfn[u]) cut[i]=cut[i^1]=1; 
    //        }
    //        else if(v!=fa)
    //            low[u]=min(low[u],dfn[v]);
    //	}
    //}
    
    bool vv[MAXN];
    void dfs(int x){
    	vv[x]=1;
    	eep(i,x){
    		int v=e[i].to;
    		if(vv[v]) continue;
    		dfs(v);
    	}
    }
    
    void solve(){
    	n=rd();m=rd();D=rd();
    	rep(i,1,n) fa[i]=i;
    	int x,y;
    	rep(i,1,m){
    		x=rd();y=rd();
    		add(x,y);
    		add(y,x);
    	}
    //	tarjan(1,-1);
    	int cnt1=0;
    	vv[1]=1;
    	eep(i,1){
    		int v=e[i].to;
    		if(vv[v]) continue;
    		cnt1++;
    		pushans(1,v);
    		vis[i]=1;
    		cat(1,v);
    		dfs(v);	
    	}
    	
    //	eep(i,1){
    //		if(vis[i]) continue;
    //		if(!cut[i]) continue;
    //		int v=e[i].to;	
    //		if(fnd(1)==fnd(v)) continue;
    //		pushans(1,v);cnt1++;vis[i]=1;vis[i^1]=1;
    //		cat(1,v);
    //	}
    	eep(i,1){
    		if(cnt1>=D) break;
    		if(vis[i]) continue;
    		int v=e[i].to;
    		if(fnd(1)==fnd(v)) continue;
    		cat(1,v);
    		vis[i]=1;vis[i^1]=1;
    		pushans(1,v);cnt1++;
    	}
    //	debug(cnt1);
    	if(cnt1!=D){
    		shit();return;	
    	}
    	
    	for(int i=2;i<=ecnt;i++){
    		if(vis[i]) continue;
    		int u=e[i^1].to,v=e[i].to;
    		if(u==1||v==1) continue;
    		if(fnd(u)==fnd(v)) continue;
    		cat(u,v);
    		pushans(u,v);
    		vis[i]=1;vis[i^1]=1;
    	}
    	rep(i,1,n){
    		if(fnd(i)!=fnd(1)){
    //			debug(fnd(i),fnd(1));
    //			debug(i);
    			shit();
    			return;
    		}
    	}
    	good();
    	rep(i,1,n-1){
    		printf("%d %d
    ",ans[i][0],ans[i][1]);	
    	}
    }
    
    int main(){
    	int T=1;
    	while(T--){
    		solve();
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    pom.xml配置
    Eclipse将引用了第三方jar包的Java项目打包成jar文件的两种方法
    jar文件运行打断点
    prim算法
    Kruscal algorithm
    递归程序设计思想(看图思考2小时)
    广义表的实现(法二)
    广义表的实现
    有错误的地宫寻宝问题
    写一个数的所有加法算式
  • 原文地址:https://www.cnblogs.com/ghostcai/p/14284612.html
Copyright © 2020-2023  润新知