将这N个点依次作为源点,求最短路径,只要把这些最短路径中的最小值输出。
Floyd-Warshall算法其实就是用到了DP。求 i 到 j 的最短路径,k 为中间点编号的最大值,i 到 j 的最短路径要么包括 k, 要么不包括 k。
#include<iostream>
#include<climits>
#include<algorithm>
#define FOR(i, N) for(int i = 1; i <= (N); i++)
using namespace std;
int cost[200][200];
int MIN = INT_MAX;
int getMin(int d[200][200], int N){
int index;
MIN = INT_MAX;
FOR(i, N){
int temp = *max_element(d[i] + 1, d[i] + 1 + N);
if(temp < MIN){
MIN = temp;
index = i;
}
}
return index;
}
int Floyd(int N){
int d[200][200];
FOR(i, N)
FOR(j, N){
if(i == j)
d[i][j] = 0;
else
d[i][j] = INT_MAX / 100;
}
for(int k = 0; k <= N; k++){
FOR(i, N)
FOR(j, N){
if(k == 0)
d[i][j] = cost[i][j];
else
d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
}
}
return getMin(d, N);
}
int read(int N){
FOR(i, N)
FOR(j, N){
if(i == j)
cost[i][j] = 0;
else
cost[i][j] = INT_MAX / 100;
}
FOR(i, N){
int m;
cin >> m;
while(m--){
int k, y;
cin >> k >> y;
cost[i][k] = y;
}
}
}
int main(){
int N;
while(cin >> N && N != 0){
read(N);
int temp = Floyd(N);
if(MIN == INT_MAX)
cout << "disjoint" << endl;
else
cout << temp << " " << MIN << endl;
}
}