转载请注明出处:http://blog.csdn.net/u012860063
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4034
3 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
Case 1: 6 Case 2: 4 Case 3: impossible
题意:就是找出边数最小的原始图,输出边数即可!
思路:就是遍历原有的边数,判断有那些边是可以去掉的,用Floyd就好!
代码如下:
#include <cstdio> #include <cmath> #include <cstring> #include <string> #include <cstdlib> #include <climits> #include <ctype.h> #include <queue> #include <stack> #include <vector> #include <deque> #include <set> #include <iostream> #include <algorithm> using namespace std; #define PI acos(-1.0) #define INF 0xffffff int n,coun,i,j,k; int map[147][147]; void init() { memset(map,0,sizeof(map)); } int Floyd() { for(i = 1 ; i <= n ; i++) { for(j = 1 ; j <= n ; j++) { if(map[i][j] == 0) continue; for(k = 1 ; k <= n ;k++) { if( map[i][k] != 0 && map[k][j] != 0) { if(map[i][j] > map[i][k] + map[k][j]) //不可能存在折线的路径比直线的路径短,如果出现则可判断这样的图表不存在 return 0; else if(map[i][j] == map[i][k] + map[k][j]) { coun--; break; } } } } } return coun; } int main() { int T,cas; while(~scanf("%d",&T)) { cas = 0; while(T--) { coun = 0; init(); scanf("%d",&n); for(i = 1; i <= n ; i++) { for(j = 1 ; j <= n ; j++) { scanf("%d",&map[i][j]); if(map[i][j] != 0) coun++; } } int ans = Floyd(); if(ans != 0) printf("Case %d: %d\n",++cas,ans); else printf("Case %d: impossible\n",++cas); } } return 0; }
原文地址:http://blog.csdn.net/u012860063/article/details/25736995