社区讨论
神秘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 条回复,欢迎继续交流。
正在加载回复...