标签:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 2058 Accepted Submission(s): 1030
题意:给出由已知点求出的每个点间的最短路,问你原先的图中最少有几个点
题解:对已经给出的最短路再求一遍最短路用Floyd ,如果在求得过程中发现有dist[i][j]>dist[i][k]+dist[k][j]的情况就说明所给的不是最短的路图,及impossible
而在求解的过程中,当dist[i][j]==dist[i][k]+dist[k][j]的时候说明从i 到j 的长度,可以通过k点到达,故可以将直接相连的i,j去掉,及标记dist[i][j] = INF;
注意两点: 1,可以先将impossible的情况单独先算出来,以防后面对dist[i][j] = INF ;
2, 当i==j||j==k||j==k 的时候要continue掉,因为这个为0的点会更新其他所有的点
下面是代码
1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 using namespace std; 5 #define N 103 6 #define INF 0x1fffffff 7 int mp[N][N]; 8 int dist[N][N]; 9 int main() 10 { 11 int i , j , k ; 12 int n; 13 int t ; 14 cin>>t; 15 int c = 0; 16 while(t--) 17 { 18 c++; 19 scanf("%d",&n); 20 for( i = 0 ; i < n ;i++) 21 { 22 for( j = 0 ; j < n ;j++) 23 { 24 scanf("%d",&mp[i][j]); 25 dist[i][j] = mp[i][j]; 26 } 27 } 28 bool flag = true; 29 for(k = 0 ;flag && k < n ; k++) 30 { 31 for(i = 0 ;flag && i < n ; i++) 32 { 33 for( j = 0 ; flag&& j < n ;j++) 34 { 35 if(dist[i][j]>dist[i][k]+dist[k][j]) 36 flag = false; 37 } 38 } 39 } 40 int cnt = 0; 41 if(flag) 42 { 43 for( k = 0 ; k < n ;k++) 44 { 45 for(i = 0 ; i < n ;i++) 46 { 47 for(j = 0 ;j < n ;j++) 48 { 49 if(i==j||j==k||k==i) continue; 50 if(dist[i][j]==dist[i][k]+dist[k][j]) 51 { 52 dist[i][j] = INF; 53 //printf("%d %d %d\n", k ,i , j); 54 cnt++; 55 } 56 } 57 } 58 } 59 } 60 if(flag) printf("Case %d: %d\n",c,n*(n-1)-cnt); 61 else printf("Case %d: impossible\n",c); 62 63 } 64 return 0 ; 65 }
标签:
原文地址:http://www.cnblogs.com/shanyr/p/4678652.html