题意:给出n个点0~(n-1),m条边(单向),q次操作。操作有两种:0:标记x点,如果标记了就输出"ERROR! At point x”。 1: 问从 x 到 y 的最短路(x,y和经过的点都必须被 标记过),如果x,或y没有被标记过输出“ERROR! At path x to y”,如果没有路输出“No such path”。
对于这个题Floyd就非常适用了,只要标记一个点,就以这个点作为中间结点,缩短一下任意两点节点之间的距离。整个过程的时间复杂度最多为O(n^3+q)。
这题就是理解Floyd算法的最外面k的意义
import java.util.Scanner;
public class hdu3631 {
static int INF = 99999999;
static int n,m,Q,a,b,c,op;
static boolean[] vis;
static int[][] dp;
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int T = 0;
while(in.hasNext()) {
n = in.nextInt();
m = in.nextInt();
Q = in.nextInt();
if(n==0)
break;
if(T>0)
System.out.println();//日,这格式问题 PE
dp = new int[n][n];
vis = new boolean[n];
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)//初始化
if(i!=j)
dp[i][j] = INF;
else
dp[i][j] = 0;
for(int i=0;i<m;i++) {
a = in.nextInt();
b = in.nextInt();
c = in.nextInt();
dp[a][b] = Math.min(c, dp[a][b]);
}
++T;
System.out.println("Case "+T+":");
while(Q-->0) {
op = in.nextInt();
if(op==0) {
int x = in.nextInt();
if(vis[x])
System.out.println("ERROR! At point "+x);
else {
vis[x] = true;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(dp[i][j]>dp[i][x] + dp[x][j])
dp[i][j] = dp[i][x] + dp[x][j];
}
} else if(op==1) {
a = in.nextInt();
b = in.nextInt();
if(!vis[a] || !vis[b])
System.out.println("ERROR! At path "+a+" to "+b);
else if(dp[a][b]<INF)
System.out.println(dp[a][b]);
else
System.out.println("No such path");
}
}
}
}
}