Description |
给定一个有权图的每两个节点间的最短路径长度,判断能否找到原图。 |
Input |
输入包括多组测试,每组测试的第一行为一个整数N,N<=100,表示图中有N个节点,然后是N行,每行有 N个整数,第i行的第j个整数k表示从i节点到j节点的最短路径距离为k,k<1000000. |
Output |
对于每组测试数据,如果能够找到原图,则输出构成原图所需要的最少边数,否则输出“impossible“。 |
Sample Input |
3 0 1 1 1 0 1 1 1 0 3 0 1 3 4 0 2 7 3 0 3 0 1 4 1 0 2 4 2 0 |
Sample Output |
6 4 impossible |
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
#include<stdio.h> #include<string.h> int g[102][102]; int main() { int n,i,j,k,flag,tot; while(scanf("%d",&n)!=EOF) { int v[102][102]; memset(v,0,sizeof(v)); for(i=0;i<n;i++) for(j=0;j<n;j++) scanf("%d",&g[i][j]); flag=0; tot=0; for(k=0;k<n;k++) for(i=0;i<n;i++) for(j=0;j<n;j++) { if(i!=k&&i!=j&&j!=k) { if(g[i][k]+g[k][j]==g[i][j]&&!v[i][j]) { tot++; v[i][j]=1; } else if(g[i][k]+g[k][j]<g[i][j]) { flag=1; goto loop; } } } loop:if(!flag) printf("%d\n",n*n-n-tot); else printf("impossible\n"); } return 0; }