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/