题意:
给定有向图任意两点的最短距离。问,这样的图存在吗?存在的话输出这个图最少可以有的边长,不存在就impossible咯==
解:
比赛的时候看那么多人过,于是我们开始搞这题。
就是floyd算法。任意两点的距离嘛。。。先想怎么impossible。如果存在最短距离小于他给的最小距离,就impossible了。看第三个样例就知道了。
然后肿么possible呢,当然最短距离是那个给的距离,就possible了。关于输出边数的话,如果给出的长度等于最短距离的话,那么他就不属于这张大图了,因为他可以由其他边得到。
WA了两次,思路还是不够明晰~
/*
Pro: 0
Sol:
date:
*/
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <set>
#include <vector>
using namespace std;
int map[110][110],n,t,sign[110][110],ans;
void floyd(){
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
for(int k= 1; k <= n; k ++)
if(k != i && k != j )
//如果相等的话,就不要ij了。我原来想的是,要ij不要ik kj。。。反了。
if(map[i][k] + map[k][j] == map[i][j])
sign[i][j] = 1;
}
bool judge(){
for(int i = 1; i <= n; i ++)
for(int j = 1; j <= n; j ++)
for(int k= 1; k <= n; k ++)
if(k != i && k != j)
if(map[i][k] + map[k][j] < map[i][j])
return false;
return true;
}
int main(){
scanf("%d",&t);
for(int ca = 1; ca <= t; ca ++){
scanf("%d",&n);
memset(map,0,sizeof(map));
memset(sign,0,sizeof(sign));
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n;j ++){
scanf("%d",&map[i][j]);
}
}
if(!judge()) printf("Case %d: impossible\n",ca);
else{
floyd(); ans = 0;
for(int i = 1; i <= n; i ++){
for(int j = 1; j <= n; j ++){
// cout << sign[i][j] << " ";
if(!sign[i][j] && map[i][j])
ans ++;
}
// cout << endl;
}
printf("Case %d: %d\n",ca,ans);
}
}
return 0;
}