zoukankan      html  css  js  c++  java
  • [AGC018]F

    Time limit : 2sec / Memory limit : 256MB

    Problem Statement

    There are two rooted trees, each with (N) vertices. The vertices of each tree are numbered (1) through (N). In the first tree, the parent of Vertex (i) is Vertex (A_i). Here, (A_i=−1) if Vertex (i) is the root of the first tree. In the second tree, the parent of Vertex (i) is Vertex (B_i). Here, (B_i=−1) if Vertex i is the root of the second tree.

    Snuke would like to construct an integer sequence of length (N), (X_1 , X_2 , … , X_N), that satisfies the following condition:

    For each vertex on each tree, let the indices of its descendants including itself be (a_1 , a_2 , …, a_k).Then, (abs(X_{a_1}+X{a_2}+…+X{a_k})=1) holds.
    Determine whether it is possible to construct such a sequence. If the answer is possible, find one such sequence.

    Constraints

    • (1≤N≤10^5)
    • (1≤A_i≤N), if Vertex (i) is not the root in the first tree.
    • (A_i=−1), if Vertex (i) is the root in the first tree.
    • (1≤B_i≤N), if Vertex (i) is not the root in the second tree.
    • (B_ii=−1), if Vertex (i) is the root in the second tree.
    • Input corresponds to valid rooted trees.

    Input

    The input is given from Standard Input in the following format:

    (N)
    (A_1 A_2 .. A_N)
    (B_1 B_2 .. B_N)

    Output

    If it is not possible to construct an integer sequence that satisfies the condition, print IMPOSSIBLE. If it is possible, print POSSIBLE in the first line. Then, in the second line, print (X_1 , X_2 , … , X_N), an integer sequence that satisfies the condition.

    Sample Input 1

    5
    3 3 4 -1 4
    4 4 1 -1 1

    Sample Output 1

    POSSIBLE
    1 -1 -1 3 -1

    Sample Input 2

    6
    -1 5 1 5 1 3
    6 5 5 3 -1 3

    sample output 2

    IMPOSSIBLE

    题意

    给出两棵树,要求给两棵树上相同编号的点赋值,使得每个点的子树权值和的绝对值为1

    分析

    首先可以给每个点的权值确定奇偶性,如果一点在两棵树上奇偶性不同那么一定不存在合法的构造方案(奇数权值节点有偶数个儿子,偶数权值节点有奇数个儿子)
    可以发现,如果构造合法解,可以只用到0,-1,1这三种权值,构造方法如下:
    如果一个点的权值为偶数,那么这个点的权值为0
    然后开始处理奇数点,每个父亲考虑给自己的儿子两两在新图上连边,表示父亲给儿子分配冲突(-11
    如果父亲为偶数点,那么当前父亲子树权值取决于两两匹配后剩下那个儿子的子树权值;否则父亲为奇数点则子树权值取决于当前点的权值
    所以在两两连边时,如果有偶数点,相当于拿 决定这个点子树权值的那个奇数点 与另一点连边
    易证出新图一定能进行二分图染色(因为不存在奇环),就能得出奇数点的权值


    CODE

    #include<bits/stdc++.h>
    using namespace std;
    vector<int>a[101010],b[101010];
    int n,root1,root2,doe;
    int id[101010],v[101010];
    int pre[808080],son[808080],now[101010];
    void add(int x,int y)
    {
    	++doe;
    	pre[doe]=now[x];
    	now[x]=doe;
    	son[doe]=y;
    }
    void connect(int x,int y)
    {
    	x=id[x]; y=id[y];
    	add(x,y); add(y,x);
    }
    
    void dfs1(int x)
    {
    	int len=a[x].size();
    	for (int i=0;i<len;++i)
    	{
    		int y=a[x][i];
    		dfs1(y);
    		if (i%2==1) connect(a[x][i],a[x][i-1]);
    	}
    	if (len%2==1) id[x]=id[a[x][len-1]];
    }
    void dfs2(int x)
    {
    	int len=b[x].size();
    	for (int i=0;i<len;++i)
    	{
    		int y=b[x][i];
    		dfs2(y);
    		if (i%2==1) connect(b[x][i],b[x][i-1]);
    	}
    	if (len%2==1) id[x]=id[b[x][len-1]];
    }
    void col(int x)
    {
    	int p=now[x];
    	while (p)
    	{
    		int y=son[p];
    		if (v[y]==0)
    		{
    			v[y]=-v[x];
    			col(y);
    		}
    		p=pre[p];
    	}
    }
    int main()
    {
    	freopen("F.in","r",stdin);
    	freopen("F.out","w",stdout);
    
    	scanf("%d",&n);
    	int x;
    	for (int i=1;i<=n;++i)
    	{
    		scanf("%d",&x);
    		if (x==-1) root1=i;
    		else a[x].push_back(i);
    	}
    	for (int i=1;i<=n;++i)
    	{
    		scanf("%d",&x);
    		if (x==-1) root2=i;
    		else b[x].push_back(i);
    	}
    	for (int i=1;i<=n;++i) if (a[i].size()%2 != b[i].size()%2)
    	{
    		printf("IMPOSSIBLE
    ");
    		return 0;
    	}
    	
    	for (int i=1;i<=n;++i) id[i]=i;
    	dfs1(root1);
    	for (int i=1;i<=n;++i) id[i]=i;
    	dfs2(root2);
    	for (int i=1;i<=n;++i) if (a[i].size()%2==0 && v[i]==0)
    	{
    		v[i]=1;
    		col(i);
    	}
    	printf("POSSIBLE
    ");
    	for (int i=1;i<=n;++i) printf("%d ",v[i]);
    	printf("
    ");
    	return 0;
    }
    
  • 相关阅读:
    MinDoc v0.6 发布,轻量级文档在线管理系统
    PostMessage和SendMessage有什么区别?(有EnumChildWindowsProc的例子)
    将QuickReport报表保存为图片(使用TMetaFile和TMetafileCanvas)
    如何将JPEG缩略图放到LISTVIEW中(delphi listview自绘图形)
    栈和队列
    SQL调优日志--内存问题
    Nancy之实现API
    JAVA和.NET互调用
    NET Core环境并创建运行ASP.NET网站
    React Native
  • 原文地址:https://www.cnblogs.com/dogcdt/p/9549256.html
Copyright © 2011-2022 走看看