• Gym


    题意其实就是给你一个有向图 但是每个SCC里面的点数目不超过5 求最长路

    首先暴力把每个SCC里的每个点的最长路跑出来 然后拓扑排序dp

    然后因为tarjan 搜索树出来的SCC是拓扑排好序的 可以直接dp

    #include<bits/stdc++.h>
    #define MOD 1000000007
    using namespace std;
    typedef long long ll;
    const int N = 1000005;
    vector<int> g[2 * N], g2[N];
    int dfn[N], low[N], bel[N], dfc, scc;
    bool inst[N];
    int scs[N], *sct = scs;
    void scc_clr(int n) {
            fill(dfn + 1, dfn + n + 1, 0);
    }
    int dfs_scc(int u) {
            *sct++ = u;
            inst[u] = 1;
            dfn[u] = low[u] = ++dfc;
            for (int v : g[u]) {
                    if (!dfn[v]) {
                            low[u] = min(low[u], dfs_scc(v));
                    } else if (inst[v]) {
                            low[u] = min(low[u], dfn[v]);
                    }
            }
            if (dfn[u] == low[u])
                    for (++scc; *sct != u; --sct) {
                            bel[sct[-1]] = scc, inst[sct[-1]] = 0;
                    }
            return low[u];
    }
    bool vis[N];
    int dp[N], du[N];
    int ans = 0;
    queue<int> que;
    int doit(int x, int y) {
            if (vis[x]) {
                    return 0;
            }
            if (bel[x] != y) {
                    return dp[x];
            }
            int anser = 1;
            vis[x] = 1;
            for (int v : g[x]) {
                    anser = max(anser, doit(v, y) + 1);
            }
            vis[x] = 0;
            dp[x] = max(dp[x], anser);
            ans = max(ans, dp[x]);
            return anser;
    }
    int main () {
            int n, m;
            scanf("%d %d", &n, &m);
            for (int i = 1; i <= m; i++) {
                    int u, v;
                    scanf("%d %d", &u, &v);
                    g[u].push_back(v);
            }
            for (int i = 1; i <= n; i++)
                    if (!dfn[i]) {
                            dfs_scc(i);
                    }
            for (int i = 1; i <= n; i++) {
                    g[bel[i] + n].push_back(i);
            }
            for (int i = 1; i <= scc; i++) {
                    for (int v : g[i + n]) {
                            doit(v, i);
                    }
            }
            cout << ans << endl;
    }
  • 相关阅读:
    Encoding
    F Takio与Blue的人生赢家之战
    D FFF团的怒火
    C Golden gun的巧克力
    B 倒不了的塔
    A jubeat
    17230 计算轴承半径
    10686 DeathGod不知道的事情
    10688 XYM-AC之路
    10692 XYM-入门之道
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11587193.html
Copyright © 2020-2023  润新知