戳这里:HDU 4034
//思路:根据题意可得,若 mat[i][j] > mat[i][k] + mat[k][j] 则无解;若 mat[i][j] == mat[i][k] + mat[k][j] 且分别对应 i->j i->k k->j 的三条有向边,则可以删掉 i->j 有向边使得原来 i 到 j 的最短路径不发生变化; 那么我们将输入的邻接矩阵当成一个有向完全图,不断的删除多余的边,得到只含最少边的最优解。实现起来要注意删边操作对判无解操作的影响
1 #include "bits/stdc++.h" 2 using namespace std; 3 int T, N; 4 int mat[110][110]; 5 const int INF = 0x3f3f3f3f; 6 7 int main() 8 { 9 scanf("%d", &T); 10 int t; 11 for(t = 1; t <= T; ++t) { 12 scanf("%d", &N); 13 int i, j; 14 for(i = 1; i <= N; ++i) { 15 for(j = 1; j <= N; ++j) { 16 scanf("%d", &mat[i][j]); 17 } 18 } 19 20 bool ok = 1; 21 int res = N * (N - 1); 22 int k; 23 for(k = 1; k <= N; ++k) { 24 for(i = 1; i <= N; ++i) { 25 for(j = 1; j <= N; ++j) { 26 if(i == j || j == k || k == i) { 27 continue; 28 } 29 if(mat[i][j] != INF && mat[i][j] > mat[i][k] + mat[k][j]) { //!!!!! 30 ok = 0; 31 break; 32 } 33 if(mat[i][j] == mat[i][k] + mat[k][j]) { 34 mat[i][j] = INF; 35 --res; 36 } 37 } 38 } 39 } 40 printf("Case %d: ", t); 41 if(ok == 0) { 42 printf("impossible\n"); 43 } 44 else { 45 printf("%d\n", res); 46 } 47 } 48 }
时间: 2024-10-29 10:45:46