hihor 学习日记:hihor一下 第五十四周(缩点+dfs)

http://hihocoder.com/contest/hiho54/problem/1

这次是强连通分量
在这里插入图片描述
因为强连通分量是一个回路,所以一张图的一个强连通分量可以看成一个点,
伪代码:
在这里插入图片描述

AC代码:

#include <bits/stdc++.h>

using namespace std;
#define LL long long
const int Mod = 1e9 + 7;
const int maxn = 1e5 + 5;
const double eps = 0.00000001;
const int INF = 0x3f3f3f3f;

struct Edge{
    int v, nxt;
}edge[maxn << 1], edge2[maxn << 1];

int tot, tot2, head[maxn], head2[maxn];
int dfn[maxn], low[maxn], Stack[maxn], ifin[maxn], top, in[maxn], belong[maxn];
LL gra[maxn];
int counter = 0, cnt;
LL num[maxn], sum;
int N, M;

void init(){
    cnt = top = tot = tot2 = 0;
    memset(head, -1, sizeof(head));
    memset(ifin, 0, sizeof(ifin));
    memset(head2, -1, sizeof(head2));
    memset(num, 0, sizeof(num));
    memset(dfn, 0, sizeof(dfn));
}

void addEdge(int u, int v) {
    edge[tot].v = v;
    edge[tot].nxt = head[u];
    head[u] = tot ++;
}

void addEdge2(int u, int v){
    edge2[tot2].v = v;
    edge2[tot2].nxt = head2[u];
    head2[u] = tot2 ++;
}

void Tarjan(int u) {
    dfn[u] = low[u] = ++counter;
    Stack[++ top] = u;
    ifin[u] = 1;
    for (int i = head[u]; i + 1; i = edge[i].nxt) {
        int v = edge[i].v;
        if(!dfn[v]) {
            Tarjan(v);
            low[u] = min(low[u], low[v]);
        }else if(ifin[v]) {
            low[u] = min(low[u], dfn[v]);
        }
    }
    if(dfn[u] == low[u]) {
        cnt ++;
        do {
            ifin[Stack[top]] = 0;
            belong[Stack[top]] = cnt;
        }while(Stack[top --] != u);
    }
}


void dfs(int u, LL cc) {
    sum = max(sum, cc);
    
    for (int i = head2[u]; i + 1; i = edge2[i].nxt) {
        int v = edge2[i].v;
        dfs(v, cc + num[v]);
    }
}

void print() {
    for (int i = 1; i <= N; i ++)
        num[belong[i]] += gra[i];
    for (int u = 1; u <= N; u ++) {
        for (int i = head[u]; i + 1; i = edge[i].nxt) {
            int v = edge[i].v;
            if(belong[u] != belong[v])
                addEdge2(belong[u], belong[v]);
        }
    }
    sum = 0;
    dfs(belong[1], num[belong[1]]);
    cout << sum << endl;
}

int main()
{
    init();
    cin >> N >> M;
    for (int i = 1; i <= N; i ++)
        cin >> gra[i];
    while(M --) {
        int u, v;
        cin >> u >> v;
        addEdge(u, v);
    }
    Tarjan(1);
    print();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/henu_jizhideqingwa/article/details/85176033