注意三个问题:
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