hdu 4034

来源:互联网 发布:阿里云免费企业邮箱 编辑:程序博客网 时间:2024/05/17 05:01

题意:给你图中任意两点间的最短路距离,求原图中边数最少是多少?

这题应该不难想,显然如果可以由其他边迭代到这个点的话就不用连边,只要统计一下要删去的边数,而且很明确的一点是这里迭代只需要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 IDSubmit TimeJudge StatusPro.IDExe.TimeExe.MemoryCode Len.LanguageAuthor46130992011-09-16 19:38:13Accepted4034140MS308K943 BG++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;}elseif(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");elseprintf("%d\n",num-tem);}return 0;}