这题就是Floyd变形,只要理解了Floyd算法,题目还是不难的。不过我还是WA了一次,原理是在运行Floyd的时候,误加了两个判断,以为当i,j未被标记的时候,i到j的路径不必更新,其实这是错的,去掉以后就过了。
/* * hdu3631/win.cpp * Created on: 2011-9-6 * Author : ben */ #include#include #include #include #include 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; }