社区讨论

神秘RE求调,#1 本地IDE过了

P5905【模板】全源最短路(Johnson)参与者 3已保存回复 3

讨论操作

快速查看讨论及其快照的属性,并进行相关操作。

当前回复
3 条
当前快照
1 份
快照标识符
@lysej5qp
此快照首次捕获于
2024/07/19 15:51
2 年前
此快照最后确认于
2024/07/19 16:36
2 年前
查看原帖
rt,所有用例都是RE 0ms/0B,感觉应该是一个很蠢的错误,但是找不出来()
CPP
#include <iostream>
#include <cstdio>
#include <vector>
#include <queue>
#include <string.h>
#define ll long long
using namespace std;
const int N = 3005, M = 6005, INF = 1e9;
struct edge{
    int to, weight;
    edge(int v, int w){
        to = v, weight = w;
    }
};

struct vertex{
    int ind, dis;
    vertex(int v, int w){
        ind = v, dis = w;
    }
    bool operator > (const vertex& x)const{
        return dis > x.dis;
    }
};

vector<edge> e[N];
priority_queue<vertex, vector<vertex>, greater<vertex> > h;
ll ans;
int n, m, u, v, w, DistoZero[N], u_dis, dis[N];
bool vis[N];

int main(){
    freopen("P5905.in", "r", stdin);
    freopen("P5905.out", "w", stdout);
    cin >> n >> m;
    for(int i=1; i<=m; i++){
        scanf("%d %d %d", &u, &v, &w);
        e[u].push_back(edge(v, w));
    }
    for(int i=1; i<=n; i++){
        e[0].push_back(edge(i, 0));
        DistoZero[N] = INF;
    }

    // Bellman-Ford预处理
    for(int i=1; i<=n; i++){
        int j = 0, k = 0;
        while(j <= n){
            u = j;
            v = e[u][k].to;
            DistoZero[v] = min(DistoZero[v], DistoZero[u] + e[u][k].weight); // 尝试松弛
            k++;
            while(k == e[j].size()){ j++, k=0; }
        }
    }
    
    // 重赋边权,顺便判负环
    int j = 1, k = 0; 
    while(j <= n){
        u = j;
        v = e[u][k].to;
        if(DistoZero[v] > DistoZero[u] + e[u][k].weight){
            cout << -1 << endl;
            return 0;
        }
        e[u][k].weight += (DistoZero[u] - DistoZero[v]);
        k++;
        while(k == e[j].size()){ j++, k=0; }
    }
    // 跑Dijkstra
    for(int s=1; s<=n; s++){
        // 初始化
        ans = 0;
        while(!h.empty()){ h.pop(); }
        memset(vis, 0, sizeof(vis));
        vis[s] = true;
        for(int i=1; i<=n; i++){ dis[i] = INF; }
        dis[s] = 0;
        for(int i=0; i<e[s].size(); i++){
            h.push(vertex(e[s][i].to, e[s][i].weight));
            dis[e[s][i].to] = min(dis[e[s][i].to], e[s][i].weight);
        }
        

        // 核心
        while(!h.empty()){
            u = h.top().ind;
            h.pop();
            if(vis[u]){ continue; }
            vis[u] = true;
            for(int i=0; i<e[u].size(); i++){
                v = e[u][i].to, w = e[u][i].weight;
                if(dis[v] > dis[u] + w){
                    dis[v] = dis[u] + w;
                    h.push(vertex(v, dis[v]));
                }
            }
        }
        for(int i=1; i<=n; i++){
            if(!vis[i]) ans += i * INF;
            else ans += i * (dis[i]  - (DistoZero[s] - DistoZero[i]));
        }
        printf("%lld\n", ans);
    }
    return 0;
}

回复

3 条回复,欢迎继续交流。

正在加载回复...