您的位置:首页 > 其它

AtCoder Grand Contest 018 F - Two Trees

2017-07-25 13:14 471 查看

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 Ai.
Here, Ai=−1 if
Vertex i is the root of the first tree. In the second tree, the parent of Vertex i is
Vertex Bi.
Here, Bi=−1 if
Vertex i is the root of the second tree.
Snuke would like to construct an integer sequence of length N, X1 , X2 , … , XN,
that satisfies the following condition:
For each vertex on each tree, let the indices of its descendants including itself be a1 , a2 , …, ak.
Then, abs(Xa1+Xa2+…+Xak)=1 holds.
Determine whether it is possible to construct such a sequence. If the answer is possible, find one such sequence.

Constraints

1≤N≤105
1≤Ai≤N,
if Vertex i is not the root in the first tree.
Ai=−1,
if Vertex i is the root in the first tree.
1≤Bi≤N,
if Vertex i is not the root in the second tree.
Bi=−1,
if Vertex i is the root in the second tree.
Input corresponds to valid rooted trees.

Input

Input is given from Standard Input in the following format:
N
A1 A2 .. AN
B1 B2 .. BN


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 X1 , X2 , … , XN,
an integer sequence that satisfies the condition.

Sample Input 1

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


Sample Output 1

Copy
POSSIBLE
1 -1 -1 3 -1

For example, the indices of the descendants of Vertex 3 of
the first tree including itself, is 3,1,2. It can be seen that the sample output holds abs(X3+X1+X2)=abs((−1)+(1)+(−1))=abs(−1)=1.
Similarly, the condition is also satisfied for other vertices.

Sample Input 2

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


Sample Output 2

Copy
IMPOSSIBLE

In this case, constructing a sequence that satisfies the condition is 
IMPOSSIBLE
.

Sample Input 3

Copy
8
2 7 1 2 2 1 -1 4
4 -1 4 7 4 4 2 4


Sample Output 3

Copy
POSSIBLE
1 2 -1 0 -1 1 0 -1


题意:给两棵有根树,给1到n确定一个点权使得任意一棵子树的点权和的绝对值为1

题解:欧拉回路

首先绝对值为1暗示我们模2为1,所以每个点的奇偶性就确定了,如果矛盾则不合法

否则我们想办法构造一组解:

考虑欧拉回路,在原树上的边不变,如果i的点权是奇数那么i向i+n连一条边,新建一个点,把两个根连起来,最后如果是i到i+n的边则val[i]=1,否则为-1(不存在则为0)

显然这样是符合要求的,画一画就明白了

#include <bits/stdc++.h>
#define xx first
#define yy second
#define mp make_pair
#define pb push_back
#define mset(x, y) memset(x, y, sizeof x)
#define mcpy(x, y) memcpy(x, y, sizeof x)
using namespace std;

typedef long long LL;
typedef pair <int, int> pii;

inline int Read()
{
int x = 0, f = 1, c = getchar();
for (; !isdigit(c); c = getchar())
if (c == '-')
f = -1;
for (; isdigit(c); c = getchar())
x = x * 10 + c - '0';
return x * f;
}

const int MAXN = 200005;

struct Edge { int p, v, r; };
int n, par[2][MAXN], typ[2][MAXN], rt[2], ans[MAXN], cur[MAXN];
vector <int> adj[2][MAXN];
vector <Edge> G[MAXN];

inline void Addedge(int x, int y) { G[x].pb({y, 0, G[y].size()}), G[y].pb({x, 0, G[x].size() - 1}); }

inline void Dfs(int x, int t)
{
typ[t][x] = 1;
for (auto y : adj[t][x])
Dfs(y, t), typ[t][x] ^= 1;
}

inline void Dfs(int x)
{
while (cur[x] < G[x].size())
if (G[x][cur[x]].v)
cur[x] ++;
else
{
int c = cur[x];
G[x][c].v = 1;
G[G[x][c].p][G[x][c].r].v = 1;
if (x && G[x][c].p == x + n)
ans[x] = -1;
else if (x - n && G[x][c].p == x - n)
ans[x - n] = 1;
Dfs(G[x][c].p);
}
}

int main()
{
#ifdef wxh010910
freopen("data.in", "r", stdin);
#endif
n = Read();
for (int i = 1; i <= n; i ++)
par[0][i] = Read(), rt[0] = par[0][i] == -1 ? i : rt[0], adj[0][par[0][i]].pb(i);
for (int i = 1; i <= n; i ++)
par[1][i] = Read(), rt[1] = par[1][i] == -1 ? i : rt[1], adj[1][par[1][i]].pb(i);
Dfs(rt[0], 0);
Dfs(rt[1], 1);
for (int i = 1; i <= n; i ++)
if (typ[0][i] ^ typ[1][i])
return puts("IMPOSSIBLE"), 0;
puts("POSSIBLE");
for (int i = 1; i <= n; i ++)
if (~par[0][i])
Addedge(par[0][i], i);
else
Addedge(0, i);
for (int i = 1; i <= n; i ++)
if (~par[1][i])
Addedge(par[1][i] + n, i + n);
else
Addedge(0, i + n);
for (int i = 1; i <= n; i ++)
if (typ[0][i])
Addedge(i, i + n);
Dfs(0);
for (int i = 1; i <= n; i ++)
printf("%d%c", ans[i], i == n ? '\n' : ' ');
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: