Title description (transferred from Rokua)
Amoeba is a good friend of Xiao Qiang.
The amoeba and the cockroach catch the Grasshopper on the Prairie. Xiao Qiang suddenly thought, the fruit grasshopper by their catch extinction, then eat grasshopper bird will starve to death, and birds of prey will also follow extinction, resulting in a series of ecological disaster.
Learning the amoeba of a creature tells the little strong that the grassland is an extremely stable ecological system. If the grasshopper is extinct, the bird can eat other insects, so the extinction of a species does not necessarily cause a major catastrophe.
We now look at this problem from a professional point of view. We use a graph called the food web to describe the relationship between organisms:
A food net has n points, which represent n species, and if biological x can eat biological y, then a forward edge from Y to X is attached.
This figure has no ring.
There are some points in the graph that are not connected to the edges, which represent the creatures that are producers that can survive through photosynthesis, while the dots that connect the edges represent the consumers who must survive by eating other organisms.
If all the food of a consumer is extinct, it will go extinct.
We define the "disaster value" of a creature in the food web as if it were suddenly extinct, then it would follow the species of extinct organisms.
For example: On a pasture, the relationship between organisms is:
If Xiao Qiang and amoeba frighten all the sheep on the Prairie, wolves will be extinct because there is no food, and cockroaches and amoeba can survive by eating cows and cows. So, the goat's disaster value is 1. However, if the grass suddenly extinction, then the entire grassland of the 5 species are not spared, so the disaster value of the grass is 4.
Given a food net, you ask for the disaster value of each creature.
Input
the first line of the input file catas.in is a positive integer N, which represents the number of mobs. Mobs from 1 to N.
next N rows, each row describes a list of other organisms that a creature can eat, formatted with several numbers separated by a blank space, each number representing the label of a creature, and the last number 0 indicates the end of the list.
Output
Contains n rows, one integer per line, representing the disaster value for each mob.
Sample input
5
0
1 0
1 0
2 3 0
2 0
Sample output
4
1
0
0
0
Exercises
Topological sorting + refactoring tree + Multiply LCA
The n^2 algorithm of violence is certainly not working, and we need to consider special practices.
Because every time there is only one biological extinction, and only if all food of x is extinct, x will be extinct.
So x is extinct when the food from the top to bottom can be reached together.
According to this we can reconstruct the tree and run the LCA.
First, all the points without food (described in the topic as "producers") are connected to one side of the 0.
The original image is then sorted in topological order to get the sequence of each point in the queue.
Then sweep forward from the back, and for each point, evaluate the LCA (22) for all of its food nodes and connect this point to the LCA.
As we add a side to the "producer"->0, it makes it possible to add a tree instead of a forest.
Each refactoring, do not need LCT, directly as a new node X,f[x][0]=lca, and then deal with the line.
The last requirement is the subtree size-1, so the topological ordering (that is, a BFS sequence) upward update can be.
#include <cstdio> #include <cstring> #include <algorithm>using namespace Std;int N, head[70000], to[ 1000000], next[1000000], CNT, rd[70000], q[70000], L = 1, R, Fa[70000][20], deep[70000], log[70000], si[70000];v OID Add (int x, int y) {to[++cnt] = y;next[cnt] = head[x];head[x] = cnt;} void Topsort () {int I, J, x;for (i = 0; I <= n; i + +) for (j = head[i]; j; j = Next[j]) Rd[to[j]] + +; for (i = 0; i <= N; i + +) if (!rd[i]) q[++r] = I;while (l <= r) {x = q[l + +];for (i = head[x]; i; i = Next[i]) {Rd[to[i]]--; if (!rd[to[i]]) Q[++R] = To[i];}} int LCA (int x, int y) {int i;if (deep[x] < deep[y]) swap (x, y); for (i = log[deep[x]-deep[y]]; ~i; i--) if (Deep[x]- (1 << i) >= deep[y]) x = fa[x][i];if (x = = y) return x;for (i = log[deep[x]]; ~i; i--) if (fa[x][i]! = Fa[y][i]) x = Fa[x][i], y = Fa[y][i];return fa[x][0];} int main () {int I, J, T, x;scanf ("%d", &n), for (i = 1; I <= n; i + +) {scanf ("%d", &t), if (!t) Add (i, 0); El Se{dO{add (i, t); scanf ("%d", &t);} while (t);}} Topsort (); for (i = 2; I <= n + 1; i + +) log[i] = log[i >> 1] + 1;for (i = n; i; i--) {x = Q[i], t = to[head[ X]];for (j = next[head[x]]; j = next[j]) T = LCA (T, To[j]); fa[x][0] = t;deep[x] = deep[t] + 1;for (j = 1; J <= Log [Deep[x]]; J + +) Fa[x][j] = fa[fa[x][j-1]][j-1];} for (i = 1; I <= n; i + +) Si[q[i]] + +, Si[fa[q[i]][0] + + si[q[i]];for (i = 1; I <= n; i + +) printf ("%d\n", si [i]-1); return 0;}
"bzoj2815" [ZJOI2012] Disaster topology sequencing + construction + multiplication LCA