zoukankan      html  css  js  c++  java
  • AGC029F Construction of a tree

    Link
    我们把每个集合看做左部点,每个数看做右部点,一个集合和这个集合中的数连边,那么可以构成一个二分图。
    我们把这棵树任选一个点作为根,让每个集合匹配这条边两端中深度较大的那个点,那么就会得到一个去掉根之后的完美匹配。
    注意到这是一个无根树,所以我们必须满足去掉任意一个右部点,这个二分图都有完美匹配。
    不难发现这个条件也是充分的。
    先求出一个完美匹配,然后从(1)开始在二分图上bfs,如果图不连通那么说明无解。bfs的时候可以顺便把方案构造了。

    #include<queue>
    #include<cstdio>
    #include<cctype>
    const int N=100007;
    std::vector<int>e[N];std::queue<int>q;
    int vis[N],mat[N],tam[N];
    int read(){int x=0,c=getchar();while(isspace(c))c=getchar();while(isdigit(c))(x*=10)+=c&15,c=getchar();return x;}
    int dfs(int u,int root)
    {
        for(int v:e[u]) if(vis[v]^root) if(vis[v]=root,!mat[v]||dfs(mat[v],root)) return mat[v]=u;
        return 0;
    }
    int main()
    {
        int n=read();
        for(int i=1;i<n;++i) for(int j=read();j;--j) e[read()].push_back(i);
        for(int i=2;i<=n;++i) if(!dfs(i,i)) return puts("-1"),0;
        q.push(1);
        for(int i=1,u;i<=n;++i)
        {
    	if(q.empty()) return puts("-1"),0;
    	u=q.front(),q.pop();
    	for(int v:e[u]) if(!tam[v]) tam[v]=u,q.push(mat[v]);
        }
        for(int i=1;i<n;++i) printf("%d %d
    ",tam[i],mat[i]);
    }
    
  • 相关阅读:
    第08组 Alpha冲刺 (6/6)
    第08组 Alpha冲刺 (5/6)
    第08组 Alpha冲刺 (4/6)
    第08组 Alpha冲刺 (3/6)
    第08组 Alpha冲刺 (2/6)
    第08组 Alpha冲刺 (1/6)
    第一次编程作业
    第01组 Alpha冲刺(6/6)(组长)
    第01组 Alpha冲刺总结(组长)
    第01组 Alpha冲刺 (5/6)(组长)
  • 原文地址:https://www.cnblogs.com/cjoierShiina-Mashiro/p/12634826.html
Copyright © 2011-2022 走看看