#include <stdio.h>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1<<27;
const int N = 1002;
int path[N][N];
bool vis[N];
int m, n, q;
int Min(int a, int b)
{
return a > b ? b : a;
}
void floyd(int k)
{
int i, j;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
if(path[i][k] < INF && path[k][j] < INF)
{
path[i][j] = Min(path[i][j], path[i][k] + path[k][j]);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
int i, j, A, B, C, ord, flag = 0, kase = 0, v, w;
while(~scanf("%d%d%d", &n, &m, &q))
{
if(n + m + q == 0) break;
if(flag) printf("\n");
flag = 1;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
path[i][j] = 0;
if(i != j) path[i][j] = INF;
}
memset(vis, false, sizeof(vis));
for(i = 0; i < m; i ++)
{
scanf("%d%d%d", &A, &B, &C);
path[A][B] = Min(path[A][B], C);
}
printf("Case %d:\n", ++ kase);
for(i = 0; i < q; i ++)
{
scanf("%d", &ord);
if(!ord)
{
scanf("%d", &v);
if(vis[v]) printf("ERROR! At point %d\n", v);
else
{
vis[v] = true;
floyd(v);
}
}
else
{
scanf("%d%d", &v, &w);
if(!vis[v] || !vis[w]) printf("ERROR! At path %d to %d\n", v, w);
else if(path[v][w] == INF) printf("No such path\n");
else printf("%d\n", path[v][w]);
}
}
}
return 0;
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int INF = 1<<27;
const int N = 1002;
int path[N][N];
bool vis[N];
int m, n, q;
int Min(int a, int b)
{
return a > b ? b : a;
}
void floyd(int k)
{
int i, j;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
if(path[i][k] < INF && path[k][j] < INF)
{
path[i][j] = Min(path[i][j], path[i][k] + path[k][j]);
}
}
}
int main()
{
// freopen("in.txt","r",stdin);
int i, j, A, B, C, ord, flag = 0, kase = 0, v, w;
while(~scanf("%d%d%d", &n, &m, &q))
{
if(n + m + q == 0) break;
if(flag) printf("\n");
flag = 1;
for(i = 0; i < n; i ++)
for(j = 0; j < n; j ++)
{
path[i][j] = 0;
if(i != j) path[i][j] = INF;
}
memset(vis, false, sizeof(vis));
for(i = 0; i < m; i ++)
{
scanf("%d%d%d", &A, &B, &C);
path[A][B] = Min(path[A][B], C);
}
printf("Case %d:\n", ++ kase);
for(i = 0; i < q; i ++)
{
scanf("%d", &ord);
if(!ord)
{
scanf("%d", &v);
if(vis[v]) printf("ERROR! At point %d\n", v);
else
{
vis[v] = true;
floyd(v);
}
}
else
{
scanf("%d%d", &v, &w);
if(!vis[v] || !vis[w]) printf("ERROR! At path %d to %d\n", v, w);
else if(path[v][w] == INF) printf("No such path\n");
else printf("%d\n", path[v][w]);
}
}
}
return 0;
}
心得:刚开始看了半天愣是没看懂题,英语太差。后来题解,其实本题所说的标记节点,就是以这个点作为中转节点,缩短任意两节点之间的距离,从而刷新矩阵。
不过本题还有几点要注意:
1、数组下标要注意(有的题起始位0,有的题为1,还没弄明白);
2、End of input is indicated by a line containing N = M = Q = 0.此条件只能用体重方式定义条件,而我的while(~scanf("%d%d%d", &n, &m, &q) && (m != 0) && (n != 0) && (q != 0))被WA了N次。。。为什么。。。
3、if(path[A][B] > C) path[A][B] = path[B][A] = C;为初始化前的条件,其作用与path[A][B] = Min(path[A][B], C);相同,但也不能用。。。为什么。。。