• 【模板】Tarjan缩点+建新图+dfs树上dp


    然后是才发现洛谷的模板题之前一直没过,看了一下才发现是建新图时把方向建返了....这猪脑子。

    于是重新学了一遍Tarjan的思路,果然靠背板子的话真就一点都回忆不起来啊。

    又pass一个点叻!yep!

    P3387 【模板】缩点

    #include<bits/stdc++.h>
    
    const int N = 100005;
    
    using namespace std;
    
    struct Node {
        int nex, v;
        Node(int nex = 0, int v = 0) :
            nex(nex), v(v) { }
    } Edge[N];
    
    struct node {
        int nex, v;
        node(int nex = 0, int v = 0) :
            nex(nex), v(v) { }
    } Edgeco[N];
    
    int stot, h[10005];
    void add(int u, int v) {
        Edge[++stot] = Node(h[u], v);
        h[u] = stot;
    }
    
    int stotco, hco[10005];
    void addco(int u, int v) {
        Edgeco[++stotco] = node(hco[u], v);
        hco[u] = stotco;
    }
    
    int dfn[10005], low[10005], idc, color[10005], tp, stk[50005], cnt, sum[10005], val[10005];
    void Tarjan(int u) {
        dfn[u] = low[u] = ++ idc;
        stk[++tp] = u;
        for(int i = h[u]; i; i = Edge[i].nex) {
            int v = Edge[i].v;
            if(!dfn[v])    {
                Tarjan(v);    low[u] = min(low[v], low[u]);
            } else if(!color[v])    low[u] = min(dfn[v], low[u]);
        }
        if(dfn[u] == low[u]) {
            cnt ++; int x;
            do {
                x = stk[tp--];
                color[x] = cnt;
                sum[cnt] += val[x];
            } while(x != u);
        }
    }
    
    int n, m;
    int f[10005];
    void dfs(int u) {
        if(f[u])    return ;
        f[u] = sum[u];
        for(int i = hco[u]; i; i = Edgeco[i].nex) {
            int v = Edgeco[i].v;
            dfs(v);
            f[u] = max(f[u], sum[u] + f[v]);
        }
    }
    
    int main() {
        scanf("%d%d", &n, &m);
        for(int i = 1; i <= n; i ++)
            scanf("%d", &val[i]);
        for(int i = 1; i <= m; i ++) {
            int u, v;
            scanf("%d%d", &u, &v);
            add(u, v);
        }
        for(int i = 1; i <= n; i ++)
            if(!color[i])
                Tarjan(i);
        for(int i = 1; i <= n; i ++)
            for(int j = h[i]; j; j = Edge[j].nex) {
                int v = Edge[j].v;
                if (color[v] != color[i]) addco(color[i], color[v]);
            }
        int ans = 0;
        for(int i = 1; i <= cnt; i ++)
            if(!f[i]) {
                dfs(i);    ans = max(ans, f[i]);
            }
        printf("%d", ans);
        return 0;
    }

    然后最近看了一下之前校队选拔的题,好!难!怎么那么多DP数论,突然慌慌。但是巨巨学长说只要能做出来最简单的几道就能苟进队了,我!信!个!鬼!于是去水模板题了。

  • 相关阅读:
    Spring@Profile注解
    day 32 子进程的开启 及其用法
    day 31 udp 协议SOCK_DGRAM
    day 30 客户端获取cmd 命令的步骤
    day 29 socket 理论
    day 29 socket 初级版
    有关 组合 继承
    day 27 多态 接口 类方法 静态方法 hashlib 摘要算法模块
    新式类和经典类的区别
    day 28 hasattr getattr serattr delattr 和带__内置__ 类的内置方法
  • 原文地址:https://www.cnblogs.com/wans-caesar-02111007/p/13939007.html
Copyright © 2020-2023  润新知