【模板】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数论,突然慌慌。但是巨巨学长说只要能做出来最简单的几道就能苟进队了,我!信!个!鬼!于是去水模板题了。

 

posted @ 2020-11-06 21:25  Wans_ovo  阅读(92)  评论(0编辑  收藏  举报