为啥这两种方法答案不一样呢,第一个是错的第二个是对的
查看原帖
为啥这两种方法答案不一样呢,第一个是错的第二个是对的
657442
wusihao1931楼主2022/9/22 10:49
#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 10010, M = 200010;

int n, m;
int f[N];
int sum[N];
int dist[N];
stack<int> stk;
bool in_stk[N];
int id[N], scc_cnt;
int dfn[N], low[N], timestamp;
int h[N], e[M], ne[M], hr[N], idx;

void add(int h[], int a, int b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx;
    idx ++ ;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++ timestamp;
    stk.push(u), in_stk[u] = true;
    
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!dfn[j])
        {
            tarjan(j);
            low[u] = min(low[j], low[u]);
        }
        else if (in_stk[j]) low[u] = min(low[u], dfn[j]);
    }
    
    if (dfn[u] == low[u])
    {
        int y;
        scc_cnt ++ ;
        do
        {
            y = stk.top();
            stk.pop();
            in_stk[y] = false;
            id[y] = scc_cnt;
            sum[scc_cnt] += dist[y];
        } while (y != u);
    }
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    memset(hr, -1, sizeof hr);
    
    for (int i = 1; i <= n; i ++ ) scanf("%d", &dist[i]);
    
    while (m -- )
    {
        int a, b;
        scanf("%d %d", &a, &b);
        add(h, a, b);
    }
    
    for (int i = 1; i <= n; i ++ )
        if (!dfn[i])
            tarjan(i);
    
    for (int i = 1; i <= n; i ++ )
        for (int j = h[i]; j != -1; j = ne[j])
        {
            int k = e[j];
            int a = id[i], b = id[k];
            if (a != b) add(hr, a, b);
        }
    
    int ans = 0;    
    for (int i = scc_cnt; i ; i -- )
    {
        if (!f[i]) f[i] = sum[i];
        for (int j = hr[i]; j != -1; j = ne[j])
        {
            int k = e[j];
            if (f[k] < f[i] + sum[k])
            {
                f[k] = f[i] + sum[k];
                ans = max(ans, f[k]);
            }
        }
    }
    
    cout << ans << endl;
    
    return 0;
}

#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>

using namespace std;

const int N = 10010, M = 200010;

int n, m;
int f[N];
int sum[N];
int dist[N];
stack<int> stk;
bool in_stk[N];
int id[N], scc_cnt;
int dfn[N], low[N], timestamp;
int h[N], e[M], ne[M], hr[N], idx;

void add(int h[], int a, int b)
{
    e[idx] = b;
    ne[idx] = h[a];
    h[a] = idx;
    idx ++ ;
}

void tarjan(int u)
{
    dfn[u] = low[u] = ++ timestamp;
    stk.push(u), in_stk[u] = true;
    
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!dfn[j])
        {
            tarjan(j);
            low[u] = min(low[j], low[u]);
        }
        else if (in_stk[j]) low[u] = min(low[u], dfn[j]);
    }
    
    if (dfn[u] == low[u])
    {
        int y;
        scc_cnt ++ ;
        do
        {
            y = stk.top();
            stk.pop();
            in_stk[y] = false;
            id[y] = scc_cnt;
            sum[scc_cnt] += dist[y];
        } while (y != u);
    }
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    memset(hr, -1, sizeof hr);
    
    for (int i = 1; i <= n; i ++ ) scanf("%d", &dist[i]);
    
    while (m -- )
    {
        int a, b;
        scanf("%d %d", &a, &b);
        add(h, a, b);
    }
    
    for (int i = 1; i <= n; i ++ )
        if (!dfn[i])
            tarjan(i);
    
    for (int i = 1; i <= n; i ++ )
        for (int j = h[i]; j != -1; j = ne[j])
        {
            int k = e[j];
            int a = id[i], b = id[k];
            if (a != b) add(hr, a, b);
        }
    
    int ans = 0;    
    for (int i = scc_cnt; i ; i -- )
    {
        if (!f[i]) f[i] = sum[i];
        for (int j = hr[i]; j != -1; j = ne[j])
        {
            int k = e[j];
            if (f[k] < f[i] + sum[k]) f[k] = f[i] + sum[k];
        }
    }
    
    for (int i = 1; i <= scc_cnt; i ++ )
        if (f[i] > ans) ans = f[i];
    cout << ans << endl;
    
    return 0;
}
2022/9/22 10:49
加载中...