dijkstra不可求最长路,只有81分,错误正确代码附上
查看原帖
dijkstra不可求最长路,只有81分,错误正确代码附上
657442
wusihao1931楼主2022/9/24 09:14

dijkstra

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

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 500010, M = 2 * N, INF = 0x3f3f3f3f;

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

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

void tarjan(int u)
{
    low[u] = dfn[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[u], low[j]);
        }
        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;
            if (monkey[y] != INF) sum[scc_cnt] += monkey[y];
        } while (y != u);
    }
}

void dijkstra(int s)
{
    priority_queue<PII, vector<PII>, greater<PII>> q;
    memset(dist, -0x3f, sizeof dist);
    dist[id[s]] = sum[id[s]];
    q.push({dist[id[s]], id[s]});
    
    while (q.size())
    {
        auto t = q.top();
        q.pop();
        
        int ver = t.y, distance = t.x;
        
        if (st[ver]) continue;
        st[ver] = true;
        
        for (int i = hr[ver]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] < distance + sum[j])
            {
                dist[j] = distance + sum[j];
                q.push({dist[j], j});
            }
        }
    }
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    memset(hr, -1, sizeof hr);
    memset(monkey, 0x3f, sizeof monkey);
    
    while (m -- )
    {
        int a, b;
        scanf("%d %d", &a, &b);
        add(h, a, b);
    }
    
    for (int i = 1; i <= n; i ++ )
    {
        int x;
        scanf("%d", &x);
        monkey[i] = min(x, monkey[i]);
    }
    
    cin >> s >> pub_cnt;
    while (pub_cnt -- )
    {
        int id_pub;
        scanf("%d", &id_pub);
        pub[id_pub] = true;
    }
    
    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);
        }
    
    dijkstra(s);
    long long res = 0;
    for (int i = 1; i <= n; i ++ ) 
        if (dist[id[i]] != -INF && pub[i]) res = max(res, (long long)dist[id[i]]);
        
    cout << res << endl;
    
    return 0;
}

spfa

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

#define x first
#define y second

using namespace std;

typedef pair<int, int> PII;

const int N = 500010, M = 2 * N, INF = 0x3f3f3f3f;

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

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

void tarjan(int u)
{
    low[u] = dfn[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[u], low[j]);
        }
        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] += monkey[y];
        } while (y != u);
    }
}

void dijkstra(int s)
{
    priority_queue<PII, vector<PII>, greater<PII>> q;
    memset(dist, -0x3f, sizeof dist);
    dist[id[s]] = sum[id[s]];
    q.push({dist[id[s]], id[s]});
    
    while (q.size())
    {
        auto t = q.top();
        q.pop();
        
        int ver = t.y, distance = t.x;
        
        if (st[ver]) continue;
        st[ver] = true;
        
        for (int i = hr[ver]; i != -1; i = ne[i])
        {
            int j = e[i];
            if (dist[j] < distance + sum[j])
            {
                dist[j] = distance + sum[j];
                q.push({dist[j], j});
            }
        }
    }
}

int main()
{
    cin >> n >> m;
    
    memset(h, -1, sizeof h);
    memset(hr, -1, sizeof hr);
    
    while (m -- )
    {
        int a, b;
        scanf("%d %d", &a, &b);
        add(h, a, b);
    }
    
    for (int i = 1; i <= n; i ++ ) scanf("%d", &monkey[i]);
    
    cin >> s >> pub_cnt;
    while (pub_cnt -- )
    {
        int id_pub;
        scanf("%d", &id_pub);
        pub[id_pub] = true;
    }
    
    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);
        }
    
    dijkstra(s);
    int res = 0;
    for (int i = 1; i <= n; i ++ ) 
        if (dist[id[i]] != -INF && pub[i]) res = max(res, dist[id[i]]);
        
    cout << res << endl;
    
    return 0;
}

2022/9/24 09:14
加载中...