您的位置:首页 > 其它

HDOJ 1874 畅通工程续(最短路)

2013-04-09 20:55 453 查看
超级传送门

注意三个问题:

1.无向图

2.有重边,应该选最小那条

3.如果查询的是A地点到本身,则返回0

Floyd解法:

/*HDOJ2544
作者:陈佳润
2013-04-09
*/
#include<stdio.h>
#include<string.h>
#define min(a,b) (a>b?b:a)
long int map[205][205],n;

void Floyd(){//Floyd算法
int i,k,j;
for(k=0;k<n;k++)
for(i=0;i<n;i++)
for(j=0;j<n;j++)
if(map[i][j]>map[i][k]+map[k][j])
map[i][j]=map[i][k]+map[k][j];
}

int main(){
long int m,i,a,b,c;
//freopen("1.txt","r",stdin);
while(scanf("%ld%ld",&n,&m)!=EOF){
memset(map,0x3f3f3f3f,sizeof(map));
for(i=0;i<m;i++){
scanf("%ld%ld%ld",&a,&b,&c);
map[a][b]=min(map[a][b],c);//防止两个地方有多条路,如果有,选最小的
map[b][a]=map[a][b];
}
Floyd();
scanf("%ld%ld",&a,&b);

if(a==b){//当查询的是一个地点到其本身
printf("0\n");
continue;
}
if(map[a][b]!=0x3f3f3f3f)//当存在路时
printf("%ld\n",map[a][b]);
else//当没有路时
printf("-1\n");
}
return 0;
}


Bellman算法:

/*HDOJ 1874
作者:陈佳润
2013-5-8*/
#include<iostream>
using namespace std;
#include<string.h>
#define min(a,b) (a>b?b:a)

struct Edge{
int u,v;
long int w;
}edge[1005];//存放边的结构体数组

long int dis[205];

int m;//边的数目
int n;//点的个数

bool Bellman(){
int i,k;
for(i=1;i<n;i++){//Bellman 算法
for(k=0;k<m;k++){

if(dis[edge[k].v]>edge[k].w+dis[edge[k].u]){
dis[edge[k].v]=edge[k].w+dis[edge[k].u];
}
if(dis[edge[k].u]>edge[k].w+dis[edge[k].v]){
dis[edge[k].u]=edge[k].w+dis[edge[k].v];
}
}
}
//检查负权回路
for(k=0;k<m;k++){
if(dis[edge[k].v]>edge[k].w+dis[edge[k].u]){
return false;
}
}
return true;
}

int main(){
int i,a,b;
while(cin>>n>>m){
for(i=0;i<m;i++)
cin>>edge[i].u>>edge[i].v>>edge[i].w;
cin>>a>>b;

if(a==b){
cout<<"0"<<endl;
continue;
}
memset(dis,0x3f3f3f3f,sizeof(dis));
dis[a]=0;

for(i=0;i<m;i++){
if(edge[i].u==edge[i].v)
continue;
if(edge[i].u==a)
dis[edge[i].v]=min(dis[edge[i].v],edge[i].w);
if(edge[i].v==a)
dis[edge[i].u]=min(dis[edge[i].u],edge[i].w);
}

bool temp=Bellman();
if(temp==false || dis[b]==0x3f3f3f3f)
cout<<"-1"<<endl;
else
cout<<dis[b]<<endl;

}
return 0;
}


两种算法的时间空间复杂度比较:

上为Bellman,下为Floyd

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: