这题就是Floyd变形,只要理解了Floyd算法,题目还是不难的。不过我还是WA了一次,原理是在运行Floyd的时候,误加了两个判断,以为当i,j未被标记的时候,i到j的路径不必更新,其实这是错的,去掉以后就过了。
/*
* hdu3631/win.cpp
* Created on: 2011-9-6
* Author : ben
*/
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int SIZE = 310;
const int MAX = 0x7fffffff;
int map[SIZE][SIZE];
bool marked[SIZE];
int N, M;
void init() {
int i, j, temp;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
map[i][j] = MAX;
}
map[i][i] = 0;
}
for (int k = 0; k < M; k++) {
scanf("%d%d%d", &i, &j, &temp);
if (map[i][j] > temp) {
map[i][j] = temp;
}
}
}
void Floyd(int k) {
int i, j;
for (i = 0; i < N; i++) {
for (j = 0; j < N; j++) {
if (map[i][k] < map[i][j] - map[k][j]) {
map[i][j] = map[i][k] + map[k][j];
}
}
}
}
void work() {
int T = 0, op, a, b, Q;
while (scanf("%d%d%d", &N, &M, &Q) == 3) {
if (N == 0 && M == 0 && Q == 0) {
break;
}
if (T > 0) {
putchar('\n');
}
printf("Case %d:\n", ++T);
init();
memset(marked, false, sizeof(marked));
for (int i = 0; i < Q; i++) {
scanf("%d", &op);
if (op == 0) {
scanf("%d", &a);
if (marked[a]) {
printf("ERROR! At point %d\n", a);
} else {
marked[a] = true;
Floyd(a);
}
} else {
scanf("%d%d", &a, &b);
if (marked[a] && marked[b]) {
if (map[a][b] == 0x7fffffff) {
puts("No such path");
} else {
printf("%d\n", map[a][b]);
}
} else {
printf("ERROR! At path %d to %d\n", a, b);
}
}
}
}
}
int main() {
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
#endif
work();
return 0;
}