题解:P8098 [USACO22JAN] Tests for Haybales G
这种题多积累就会做了。
adhoc
但是好像这道题啥都用不了(?)
差分约束是可以得到
题目中给的东西是比较像树的,所以可以考虑建一棵树来看看。
但是单按照题目条件建出的并不是一棵树,所以考虑将每个值加
所以现在的题目条件就是对于一个点
于是,我们可以将
我们将
现在,我们考虑求
我们现在要满足以下条件:
-
(dep_1-dep_i) \times k + p_{i}' < (dep_1-dep_{fath}) \times k + p_{fath}'
所以可以得到了:
因为
很容易想到可以使用 dfs 序来满足条件。
但是呢,还是错了,这回就比较显然了,你会
怎么办呢?
考虑正不行就反着来,所以直接将
最后让
然后就做完了。
Code
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 2e5+10;
const int M = 4e5+10;
int n, k;
int cnt, head[N];
int to[M], nxt[M];
int t, dfn[N];
int dep[N];
void connect(int u, int v) {
cnt++, nxt[cnt] = head[u];
head[u] = cnt, to[cnt] = v;
}
void dfs(int u, int from) {
dep[u] = dep[from] + 1;
dfn[u] = ++t; dfn[u] = k - dfn[u];
for (int i = head[u];i;i=nxt[i]) {
int v = to[i];
if (v == from) continue;
dfs(v, u);
}
}
int fath;
signed main() {
cin >> n; k = 1e9;
for (int i = 1;i<= n;i++) {
cin >> fath; fath++;
connect(fath, i), connect(i, fath);
} dep[0] = -1;
dfs(n + 1, 0);
cout << k << endl;
for (int i = 1;i<= n;i++) {
cout << k * (dep[1] - dep[i]) + dfn[i] << "\n";
}
return 0;
}