题意:给出一个有向图两两顶点间的最短路值,问满足条件的原图中,求出边最少的那个。
思路:首先分两种情况考虑,有解和无解;
无解:在给出的图中,如果出现dis[i][j] > dis[i][k] + dis[k][j] 则无解,也就是存在另一条路径,使得从i到j更短,则无解。
有解:开始时,先假设满足条件的图是个完全图,然后可以从里面删边,如果发现dis[i][j] == dis[i][k] + dis[k][j],则可以删除直接连接的那一条边。
#include <cstdio>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 111;
const int INF = 12345678;
int graph[N][N];
int main() {
int T;
cin >> T;
for(int _case = 0; _case < T; _case++) {
int n, ans;
cin >> n;
ans = n * (n - 1);
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= n; j++) {
scanf("%d", &graph[i][j]);
}
}
bool isOk = true;
for(int k = 1; k <= n && isOk; k++)
for(int i = 1; i <= n && isOk; i++)
for(int j = 1; j <= n && isOk; j++) {
if(i == j || i == k || j == k)
continue;
if(graph[i][j] != INF && graph[i][j] > graph[i][k] + graph[k][j]) {
isOk = false;
break;
}
if(graph[i][j] == graph[i][k] + graph[k][j]) {
ans--;
graph[i][j] = INF;
}
}
printf("Case %d: ", _case + 1);
if(!isOk) {
printf("impossible\n");
} else {
printf("%d\n", ans);
}
}
return 0;
}