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
  • 相关阅读:
    HDU1285-确定比赛名次(拓扑排序)
    ftp sftp
    Python with 用法
    odoo 非root用户运行不成功
    linux 删除软连接
    vscode wsl php
    WSL 修改默认登录用户为root
    WSL ssh服务自启动
    odoo 获取model的所有字段
    odoo 在"动作"("Action")菜单中添加子菜单, 点击子菜单弹窗自定义form
  • 原文地址:https://www.cnblogs.com/cychester/p/9811370.html
Copyright © 2011-2022 走看看