题目链接:https://www.luogu.org/problemnew/show/P3371
题意理解
这就是用来验板子的题目,讲真我这套代码跑的飞快,最大的点也就96ms我这套代码勉强能用吧。。
代码
#include <stdio.h>
// 注意点和边是从0开始编号的,如果不一样,需要修改
const int inf = 0x3f3f3f3f;
// 点的最大数,开数组用
const int maxV = 10010;
// 边的最大数,开数组用
const int maxE = 500010;
// dist[i]表示从点i到开始点的距离
int dist[maxV];
int pre[maxV];
int edge[maxE][3];
// n表示点的实际个数
int n;
// m表示边的实际个数
int m;
int relax(int u, int v, int c) {
if (dist[v] > dist[u] + c) {
dist[v] = dist[u] + c;
pre[v] = u;
return 1;
}
return 0;
}
int bellman(int src) {
for (int i = 0; i < n; i++) {
dist[i] = inf;
pre[i] = -1;
}
dist[src] = 0;
bool flag;
for (int i = 1; i < n; i++) {
flag = false; // 优化
for (int j = 0; j < m; j++) {
if (1 == relax(edge[j][0], edge[j][1], edge[j][2])) {
flag = true;
}
}
if (!flag) {
break;
}
}
for (int i = 0; i < m; i++) {
if (1 == relax(edge[i][0], edge[i][1], edge[i][2])) {
return 0; // 有负环
}
}
return 1;
}
// 需要初始化为0
int cnt;
void add_edge(int u, int v, int c) {
edge[cnt][0] = u;
edge[cnt][1] = v;
edge[cnt][2] = c;
cnt++;
}
void read(int &x) {
x = 0;
int f = 1;
char ch = getchar();
while (ch > '9' || ch < '0') {
if (ch == '-') {
f = -1;
}
ch = getchar();
}
while (ch >= '0' && ch <= '9') {
x = x * 10 + (int) (ch - 48);
ch = getchar();
}
x = x * f;
}
int main() {
int s;
read(n);
read(m);
read(s);
cnt = 0;
for (int i = 0; i < m; i++) {
int x, y, z;
read(x);
read(y);
read(z);
add_edge(x - 1, y - 1, z);
}
bellman(s - 1);
for (int i = 0; i < n; i++) {
if (dist[i] == inf) {
printf("2147483647 ");
} else {
printf("%d ", dist[i]);
}
}
return 0;
}