zoukankan      html  css  js  c++  java
  • 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
    ", ans);
    150 }
    View Code
  • 相关阅读:
    CREATE AGGREGATE
    技术文档列表
    jQuery 判断表单中多个 input text 中至少有一个不为空
    Java实现 蓝桥杯 算法提高 奥运会开幕式
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最长滑雪道
    Java实现 蓝桥杯 算法提高 最大值路径
    Java实现 蓝桥杯 算法提高 最大值路径
    Java实现 蓝桥杯 算法提高 最大值路径
  • 原文地址:https://www.cnblogs.com/cychester/p/9811370.html
Copyright © 2011-2022 走看看