BZOJ2815: [ZJOI2012]灾难
这题挺神仙的
它看上去有一些传递性,感觉要用树做
可是它不是一棵树,考虑把它变成树
对于一个点,它会灭绝当且仅当它的食物都灭绝了
这似乎可以拓扑,但随便想一想就知道是不行的
考虑它的食物都灭绝了满足什么性质
它的食物都灭绝了当且仅当它的食物的食物灭绝了
这样向前是可以追溯到一个点的
这就满足树的关系了,一个点唯一对应一个父亲节点,
他们之间满足:父节点灭绝会导致儿子节点食物灭绝进而使儿子节点灭绝
而这样恰好也满足了题目中让你求的“灾难值”
子树求 size 即可
代码:
#include <algorithm>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cstdio>
#include <vector>
#include <queue>
#include <cmath>
using namespace std;
const int MAXN = 65540;
struct EDGE{
int nxt, to;
EDGE(int NXT = 0, int TO = 0) {nxt = NXT; to = TO;}
}edge[MAXN << 1];
int n, totedge, lg;
int head[MAXN], dep[MAXN], ind[MAXN];
int f[MAXN][18], siz[MAXN], com[MAXN];
vector<int> edg[MAXN];
queue<int> q;
inline void add(int x, int y) { //x to y, son to fa
f[x][0] = y;
dep[x] = dep[y] + 1;
edge[++totedge] = EDGE(head[x], y);
head[x] = totedge;
edge[++totedge] = EDGE(head[y], x);
head[y] = totedge;
return;
}
inline void init(int x) {
for (int i = 1; i <= lg; ++i)
f[x][i] = f[f[x][i - 1]][i - 1];
return;
}
inline int lca(int x, int y) {
if (dep[x] < dep[y]) swap(x, y);
for (int i = lg; i >= 0; --i)
if (dep[f[x][i]] >= dep[y]) x = f[x][i];
if (x == y) return x;
for (int i = lg; i >= 0; --i)
if (f[x][i] != f[y][i]) x = f[x][i], y = f[y][i];
return f[x][0];
}
void dfs(int x) {
siz[x] = 1;
for (int i = head[x]; i; i = edge[i].nxt) if (edge[i].to != f[x][0]) {
int y = edge[i].to;
dfs(y);
siz[x] += siz[y];
}
return;
}
int main() {
scanf("%d", &n);
lg = (int)log2(n) + 1;
register int xx;
for (int i = 1; i <= n; ++i) {
scanf("%d", &xx);
while (xx) {
++ind[i];
edg[xx].push_back(i);
scanf("%d", &xx);
}
}
for (int i = 1; i <= n; ++i) {
com[i] = -1;
if (!ind[i]) {
q.push(i);
com[i] = 0;
}
}
while (!q.empty()) {
int x = q.front(); q.pop();
add(x, com[x]);
init(x);
for (int i = 0; i < edg[x].size(); ++i) {
register int y = edg[x][i];
com[y] = ((~com[y]) ? lca(com[y], x) : x);
--ind[y];
if (!ind[y]) q.push(y);
}
}
dfs(0);
for (int i = 1; i <= n; ++i) printf("%d\n", siz[i] - 1);
return 0;
}
禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载
,用户转载请注明出处:https://www.cnblogs.com/xcysblog/

浙公网安备 33010602011771号