洛谷 2921 在牧场万圣节

Tarjan + DAG上跑PD

 1 #include <algorithm>
 2 #include <iostream>
 3 #include <cstring>
 4 #include <cstdlib>
 5 #include <cctype>
 6 #include <cstdio>
 7 
 8 using namespace std;
 9 
10 inline void read(int &x)
11 {
12     int k = 1; x = 0;
13     char ch = getchar();
14     while (!isdigit(ch)) 
15         if (ch == '-') ch = getchar(), k = -1;
16         else ch = getchar();
17     while (isdigit(ch))
18         x = (x << 1) + (x << 3) + (ch ^ 48),
19         ch = getchar();
20     x *= k;
21 }
22 
23 const int N = 101010; 
24 int n, cnt = 0, x, top, color = 0, tag = 0, cur, cnt2 = 0;
25 int f[N], v[N], dfn[N], low[N], stk[N], col[N], F[N], in[N], sum[N], ans[N];
26 
27 struct Edge
28 {
29     int u, v, nxt;
30 }e[N << 2], E[N << 2];
31 
32 inline void Addedge(int a, int b)
33 {
34     ++cnt;
35     e[cnt].u = a;
36     e[cnt].v = b;
37     e[cnt].nxt = f[a];
38     f[a] = cnt;
39 }
40 
41 inline void addedge(int a, int b)
42 {
43     ++cnt2;
44     E[cnt2].u = a;
45     E[cnt2].v = b;
46     E[cnt2].nxt = F[a];
47     F[a] = cnt2;
48 }
49 
50 void Tarjan(int u)
51 {
52     dfn[u] = low[u] = ++tag;
53     stk[++top] = u; v[u] = 1;
54     for (int i = f[u]; i != -1; i = e[i].nxt)
55         if (!dfn[e[i].v])
56             Tarjan(e[i].v), low[u] = min(low[u], low[e[i].v]);
57         else if (v[e[i].v])
58             low[u] = min(low[u], low[e[i].v]);
59     if (dfn[u] == low[u])
60     {
61         ++color;
62         do
63         {
64             cur = stk[top--];
65             col[cur] = color;
66             ++sum[color];
67             v[cur] = 0;
68         }while (cur != u);
69     }
70 }
71 
72 void DFS(int u)
73 {
74     for (int i = F[u]; i != -1; i = E[i].nxt)
75         ans[E[i].v] += ans[u], DFS(E[i].v);
76 }
77 
78 int main()
79 {
80     read(n);
81     memset(f, -1, sizeof(f));
82     memset(F, -1, sizeof(F));
83     for (int i = 1; i <= n; ++i) { read(x); if (i != x) Addedge(i, x); }
84     for (int i = 1; i <= n; ++i) if (!dfn[i]) Tarjan(i);
85     for (int i = 1; i <= cnt; ++i)
86         if (col[e[i].v] != col[e[i].u])
87             addedge(col[e[i].v], col[e[i].u]), ++in[col[e[i].u]];
88     for (int i = 1; i <= color; ++i) ans[i] = sum[i];
89     for (int i = 1; i <= color; ++i) if (!in[i]) DFS(i);
90     for (int i = 1; i <= n; ++i) printf("%d\n", ans[col[i]]);
91     return 0;
92 }

猜你喜欢

转载自www.cnblogs.com/yanyiming10243247/p/10100338.html