cychester

Luogu3119 草鉴定-Tarjan+Topsort

Solution

简单的$Tarjan$题。

有大佬现成博客 就不写了 → 传送门

Code

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<queue>
  5 #define rd read()
  6 using namespace std;
  7 
  8 const int N = 1e5 + 5;
  9 const int inf = ~0U >> 2;
 10 
 11 int n, m;
 12 int head[N], tot, Head[N], Tot;
 13 int low[N], dfn[N], cnt;
 14 int st[N], tp, col, c[N], val[N], subsz[N], upsz[N], deg[N], bvis[N];
 15 bool vis[N];
 16 
 17 struct edge {
 18     int nxt, fr, to;
 19 }e[N], E[N];
 20 
 21 queue<int> q;
 22 
 23 int read() {
 24     int X = 0, p = 1; char c = getchar();
 25     for (; c > '9' || c < '0'; c = getchar())
 26         if (c == '-') p = -1;
 27     for (; c >= '0' && c <= '9'; c = getchar())
 28         X = X * 10 + c - '0';
 29     return X * p;
 30 }
 31 
 32 void add(int u, int v) {
 33     e[++tot].to = v;
 34     e[tot].fr = u;
 35     e[tot].nxt = head[u];
 36     head[u] = tot;
 37 }
 38 
 39 void Add(int u, int v) {
 40     E[++Tot].to = v;
 41     E[Tot].fr = u;
 42     E[Tot].nxt = Head[u];
 43     Head[u] = Tot;
 44 }
 45 
 46 void cmin(int &A, int B) {
 47     if (A > B) A = B;
 48 }
 49 
 50 void cmax(int &A, int B) {
 51     if (A < B) A = B;
 52 }
 53 
 54 void tarjan(int u) {
 55     dfn[u] = low[u] = ++cnt;
 56     vis[u] = 1; st[++tp] = u;
 57     for (int i = head[u]; i; i = e[i].nxt) {
 58         int nt = e[i].to;
 59         if (!dfn[nt]) {
 60             tarjan(nt);
 61             cmin(low[u], low[nt]);
 62         }
 63         else if (vis[nt]) cmin(low[u], dfn[nt]);
 64     }
 65     if (low[u] == dfn[u]) {
 66         col++;
 67         for (; tp;) {
 68             int z = st[tp--];
 69             c[z] = col;
 70             vis[z] = 0;
 71             val[col]++;
 72             if (z == u) break;
 73         }
 74     }
 75 }
 76 
 77 void dfs(int u) {
 78     vis[u] = 1;
 79     for (int i = Head[u]; i; i = E[i].nxt) {
 80         int nt = E[i].to;
 81         dfs(nt);
 82     }
 83 }
 84 
 85 int dfs2(int u) {
 86     if (bvis[u] == 1) return 1;
 87     if (bvis[u] == -1) return 0;
 88     if (u == c[1]) return 1;
 89     bool flag = false;
 90     for (int i = Head[u]; i; i = E[i].nxt) {
 91         int nt = E[i].to;
 92         if (dfs2(nt)) {
 93             flag = true;
 94             cmax(upsz[u], upsz[nt] + val[u]);
 95         }
 96     }
 97     bvis[u] = flag ? 1 : -1;
 98     return flag;
 99 }
100 
101 void Topsort() {
102     subsz[c[1]] = val[c[1]];
103     for (int i = 1; i <= col; ++i)
104         if (!deg[i]) q.push(i);
105     for (int u; !q.empty(); ) {
106         u = q.front(); q.pop();
107         for (int i = Head[u]; i; i = E[i].nxt) {
108             int nt = E[i].to;
109             if (subsz[u] != -inf)
110                 cmax(subsz[nt], subsz[u] + val[nt]);
111             deg[nt]--;
112             if (!deg[nt]) q.push(nt);
113         }
114     }
115 }
116 
117 int main()
118 {
119     n = rd; m = rd;
120     for (int i = 1; i <= m; ++i) {
121         int u = rd, v = rd;
122         add(u, v);
123     }
124     for (int i = 1; i <= n; ++i)
125         if (!dfn[i]) tarjan(i);
126     for (int i = 1; i <= m; ++i) {
127         int u = e[i].fr, v = e[i].to;
128         u = c[u], v = c[v];
129         if (u == v) continue;
130         Add(u, v);
131         deg[v]++;
132     }
133     memset(vis, 0, sizeof(vis));
134     for (int i = 1; i <= col; ++i) subsz[i] = -inf;
135     dfs(c[1]);
136     Topsort();
137     bvis[c[1]] = 1;
138     upsz[c[1]] = val[c[1]];
139     for (int i = 1; i <= col; ++i) 
140         if (!vis[i]) dfs2(i);
141     int ans = val[c[1]];
142     for (int i = 1; i <= m; ++i) {
143         int u = e[i].fr, v = e[i].to;
144         u = c[u]; v = c[v];
145         if (u == v) continue;
146         if (!vis[v] || !(bvis[u] == 1)) continue;
147         cmax(ans, subsz[v] + upsz[u] - val[c[1]]);
148     }
149     printf("%d\n", ans);
150 }
View Code

 

posted on 2018-10-18 16:33  cychester  阅读(186)  评论(0编辑  收藏  举报

导航