本题是找所需要的路径数,关键在于消去不必要的边。就依次找,看某点与其他点的连线是否可以通过其他点间的连线来找到,如果能的话就把总的边数减一。所以就应该找最短距离,如果最短距离等于其就可以减去1,如果小于就不成立,如果大于就不减。(关键在于理解题目中所给的条件都已经是最短边,我们就相当于验证他是不是最短边,如果通过其他边也可以达到最短边的长度那这最短边就没必要存在就减去,如果甚至可以达到比他小,那就说明条件出错,直接输出impossible就行,如果大于的话,那就说明这条边是存在的,放那就好)
#include <stdio.h>
#include <string.h>
int ans=0;
int ma[110][110];
int f[110][110];
int n;
int floyed()
{
int i,j,k;
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
if(i==j)
continue;
for(k=0;k<n;k++)
{
if(k==j||k==i)
continue;
if(f[i][j]==f[i][k]+f[k][j])
{
ans--;
break;
}
else if(f[i][k]+f[k][j]<f[i][j])
return 0;
}
}
return 1;
}
int main()
{
int t,icase;
scanf("%d",&t);
for(icase=1;icase<=t;icase++)
{
memset(ma,0,sizeof(ma));
int i,j,k;
scanf("%d",&n);
for(i=0;i<n;i++)
for(j=0;j<n;j++)
{
scanf("%d",&ma[i][j]);
f[i][j]=ma[i][j];
}
ans=n*(n-1);
int flag=floyed();
if(flag)
printf("Case %d: %d\n",icase,ans);
else
printf("Case %d: impossible\n",icase);
}
return 0;
}