转载请注明出处: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