您的位置:首页 > 其它

成都网赛1004 &hdu4034

2011-09-11 21:39 423 查看
哎,郁闷 比赛时,WA了n多次,最终也没过,以为算法错了,可想来想去感觉没错啊!以给的最短距离为边建图,然后利用floyd算所有点之间的距离,如果i到j的距离经过k则标记i到j,最后如果i到j被标记了并且求的的最短距离等于原始的(即直连的)则可以把直连的删除即总边数减一。如果求的的距离小于直连标记 输出impossible。 原来是n个点的总边数m应该为n*(n-1); 当时不知道怎么搞成了m=2*n。

View Code

#include <iostream>
#include<cstring>
#include<cstdio>
using namespace std;
int map[105][105];
int dist[105][105];
int aa[105][105];
int n;
void ford()
{
int i,j,k;

for (i=1;i<=n;i++)
for(j=1;j<=n;j++)
for(k=1;k<=n;k++)
{
if(j!=i&&i!=k&&dist[j][k]>=dist[j][i]+dist[i][k])
{
aa[j][k]=1;
dist[j][k]=dist[j][i]+dist[i][k];
}
}
}
int main()
{
int k,i,j,m,ll,gg=0;
cin>>k;
while (k--)
{
gg++;
memset(map,0,sizeof(map));
memset(dist,0,sizeof(dist));
memset(aa,0,sizeof(aa));
cin>>n;
for (i=1;i<=n;i++)
for(j=1;j<=n;j++)
{
cin>>map[i][j];
dist[i][j]=map[i][j];
}
m=n*(n-1);
ford();
int flag=0;
ll=0;
for (i=1;i<=n;i++)
for(j=1;j<=n;j++)
{

if(dist[i][j]==map[i][j]&&aa[i][j])
m--;
else{
if(dist[i][j]<map[i][j])
flag=1;

}
}
if(flag||m<n-1)  cout<<"Case "<<gg<<": "<<"impossible"<<endl;
else{

cout<<"Case "<<gg<<": "<<m<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: