输入一个有向网络图,边的权值可正可负,求顶点到其他各点的最短路。
输入
第一行输入n,表示n个结点(默认顶点为0号)
接下来输入n*n矩阵。表示各边的权值。
输出
输出一行,如果有负权回路输出“not possible”,否则输出顶点0到其他点的最短路,输出答案之间仅有一个空格,结尾没有空格。
样例输入 Copy
4 0 0 -3 0 2 0 0 0 0 -1 0 -4 0 0 0 0样例输出 Copy
not possible
负权边用 bellmanFord 和 SPFA
此题int范围不行 一直wa不知道原因 改用long long过了
bellmanFord:
#include<stdio.h>
#include<string.h>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0x7fffffff
const long long N = 1001;
long long n;
long long g[N][N];
long long dist[N];
int bellmanFord() {
for (long long i=1; i<n; i++) {
dist[i] = INF;
}
dist[0] = 0;
for (long long k=0; k<n; k++) {
int update = 0;
for (long long i=0; i<n; i++) {
for (long long j=0; j<n; j++) {
if (g[i][j] != INF && dist[i] != INF && dist[j] > dist[i] + g[i][j]) {
dist[j] = dist[i] + g[i][j];
update = 1;
}
}
}
if (!update) break;
}
for (long long i=0; i<n; i++) {
for (long long j=0; j<n; j++) {
if (dist[j] > dist[i] + g[i][j]) return 1;
}
}
return 0;
}
int main() {
while (~scanf("%lld", &n)) {
memset(g, 0, sizeof(g));
memset(dist, 0, sizeof(dist));
long long val;
for (long long i=0; i<n; i++) {
for (long long j=0; j<n; j++) {
scanf("%lld", &val);
if (val == 0 && i != j) g[i][j] = INF;
else g[i][j] = val;
}
}
int flag = bellmanFord();
if (flag) printf("not possible\n");
else {
for (long long i=1; i<n; i++) {
if (i == 1) printf("%lld", dist[i]);
else printf(" %lld", dist[i]);
}
printf("\n");
}
}
return 0;
}
SPFA:
#include<stdio.h>
#include<string.h>
#include<map>
#include<vector>
#include<algorithm>
#include<queue>
using namespace std;
#define INF 0x7fffffff
const long long N = 100101;
long long n, m;
long long visit[N], dist[N], cnt[N];
long long e[N], nex[N], w[N], now[N];
long long idx;
void add(long long a, long long b, long long c) {
e[idx] = b;
w[idx] = c;
nex[idx] = now[a];
now[a] = idx++;
}
bool spfa() {
queue<long long> que;
que.push(1);
dist[1] = 0;
visit[1] = 1;
while (!que.empty()) {
long long p = que.front();
que.pop();
visit[p] = 0;
for(long long i=now[p]; i!=-1; i=nex[i]) {
long long j = e[i];
if (dist[j] > dist[p] + w[i]) {
dist[j] = dist[p] + w[i];
cnt[j] = cnt[p] + 1;
if (cnt[j] >= n) return 1;
if (!visit[j]) {
que.push(j);
visit[j] = 1;
}
}
}
}
return 0;
}
int main() {
while(~scanf("%lld",&n)) {
memset(now, -1, sizeof(now));
memset(e, 0, sizeof(e));
memset(nex, 0, sizeof(nex));
memset(w, 0, sizeof(w));
long long val;
idx = 0;
for(long long i=1; i<=n; i++){
for (long long j=1; j<=n; j++) {
scanf("%lld", &val);
if (val == 0 && i != j) add(i, j, INF);
else add(i, j, val);
}
}
memset(dist, 0x3f, sizeof(dist));
memset(cnt, 0, sizeof(cnt));
memset(visit, 0, sizeof(visit));
int flag = spfa();
if (flag) printf("not possible\n");
else {
for (int i=2; i<=n; i++) {
if (i == 2) printf("%lld", dist[i]);
else printf(" %lld", dist[i]);
}
printf("\n");
}
}
return 0;
}