题意:给你图中任意两点间的最短路距离,求原图中边数最少是多少?
这题应该不难想,显然如果可以由其他边迭代到这个点的话就不用连边,只要统计一下要删去的边数,而且很明确的一点是这里迭代只需要1个点去迭代,因为任意两点间都是最短,那么必然存在1个点迭代使得这两点最短,假设求i->j的最短路 ,可以迭代i->k->h->g->j,肯定在中间k,h,j有一个点使得i-j最短,假设这个点是h那么必然i->h=i->k->h;h->j=h->g->j;因为都是最短路;说了这么多是为什么?因为我要将以前求flody的最外层放里面去。。。希望你能够理解为什么能这么做。
Run ID | Submit Time | Judge Status | Pro.ID | Exe.Time | Exe.Memory | Code Len. | Language | Author |
4613099 | 2011-09-16 19:38:13 | Accepted | 4034 | 140MS | 308K | 943 B | G++ | xym2010 |
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
int gp[105][105],n;
int work()
{
int flag=1,count=0;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
if(i==j)continue;
for(int k=1;k<=n;k++)
{
if(i==k||j==k)continue;
if(gp[i][j]>gp[i][k]+gp[k][j]&&gp[i][k]&&gp[k][j])
{
flag=0;
return -1;
}
else
if(gp[i][j]==gp[i][k]+gp[k][j]&&gp[i][k]&&gp[k][j])
{
count++;
break;
}
}
}
return count;
}
int main()
{
int T,t,num;
scanf("%d",&T);
for(t=1;t<=T;t++)
{
num=0;
scanf("%d",&n);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
scanf("%d",&gp[i][j]);
if(gp[i][j]!=0)num++;
}
printf("Case %d: ",t);
int tem=work();
if(tem==-1)
printf("impossible\n");
else
printf("%d\n",num-tem);
}
return 0;
}