求助,Johnson40分
查看原帖
求助,Johnson40分
466295
zeta炀楼主2022/8/20 10:11

RT,前5个点过了

#include<bits/stdc++.h>
using namespace std;

const int N = 1e5 + 5;
typedef long long ll;
typedef pair<int, int> PII;
int n, m;
ll d[N], v[N], cnt[N], h[N];
vector<PII> g[N];
vector<PII> edge[N];
priority_queue<PII, vector<PII>, greater<PII> > pq;
queue<int> q;

bool spfa(){//spfa判负环,顺便求出h数组
	for(int i = 1; i <= n; i++) h[i] = 1000000000;
	memset(v, 0, sizeof(v));
	memset(cnt, 0, sizeof(cnt));
	h[0] = 0, v[0] = 1;
	q.push(0);
	while(!q.empty()){
		int x = q.front();
		v[x] = 0;
		q.pop();
		for(PII u : g[x]){
			int k = u.first, w = u.second;
			if(h[w] > h[x] + k) {
				h[w] = h[x] + k;
				if(!v[w]) {
					q.push(w), v[w] = 1;
					if(++cnt[w] >= n) return true;
				}
			}
		}
	}
	return false;
}

void dijkstra(int s){//dijkstra跑最短路
	for(int i = 1; i <= n; i++) d[i] = 1000000000;
	memset(v, 0, sizeof(v));
	d[s] = 0;
	pq.push({0, s});
	while(!pq.empty()) {
		int x = pq.top().second;
		pq.pop();
		if(v[x]) continue;
		v[x] = 1;
		for(PII u : edge[x]) {
			int k = u.first, w = u.second;
			if(d[w] > d[x] + k) {
				d[w] = d[x] + k;
				pq.push({d[w], w});
			}
		}
	}
}

int main(){
	cin >> n >> m;
	for(int i = 1; i <= m; i++){
		int x, y, z;
		cin >> x >> y >> z;
		g[x].push_back({z, y});
	}
	for(int i = 1; i <= n; i++)
		g[0].push_back({0, i});//建立超级原点
	if(spfa()) puts("-1");//判负环
	else {
		for(int i = 1; i <= n; i++) {
			for(PII u : g[i]) {
				int w = u.first + h[i] - h[u.second];
				edge[i].push_back({w, u.second});
			}
		}//用Johnson算法更改边权
		for(int i = 1; i <= n; i++) {
			dijkstra(i);
			ll sum = 0;
			for(int j = 1; j <= n; j++)
				sum += (j * (d[j] - h[i] + h[j]));				
			cout << sum << endl;
		}//跑最短路并输出
	}
	return 0;
}

调了一早上,人都调麻了,求dalao帮调

2022/8/20 10:11
加载中...