1、题目源地址:http://acm.hdu.edu.cn/showproblem.php?pid=3790
2、基本题意:找出最短路径,若有多条最短路径,输出那条花费最小的。(注意过滤重边!)
3、源代码:
//HOJ--3790:最短路径问题 Dijkstra算法 ,注意要考虑重边(如果最短距离有多条路线,则输出花费最少的)
#include<iostream>
#include<memory.h>
#define MAX 1005
#define INF 999999999
using namespace std;
int map[MAX][MAX],cost[MAX][MAX];//分别表示两节点之间直接距离及花费
int visited[MAX],dist[MAX],min_cost[MAX];
int N,M;
int start,end;
void Dijkstra()
{
int i,j,min,pos;
memset(visited,0,sizeof(visited));
for(i=1;i<=N;i++)
{
dist[i]=map[start][i];//初始化dist[]为到start节点的距离
min_cost[i]=cost[start][i];//初始化min_cost[]为到start节点的花费
}
visited[start]=1;
for(i=1;i<=N;i++)
{
min=INF;
for(j=1;j<=N;j++)
{
if(!visited[j] && dist[j]<min)
{
pos=j;
min=dist[j];
}
}
visited[pos]=1;
for(j=1;j<=N;j++)
{
//优先考虑距离最短
if(!visited[j] && dist[pos]+map[pos][j]<dist[j])
{
dist[j]=dist[pos]+map[pos][j];//更新dist[]
min_cost[j]=min_cost[pos]+cost[pos][j]; //同时更新min_cost[]
}
//注意:求得最小花费的关键所在。如果距离相等时,若经过pos可使得花费变小 ,则更新最小花费
else if(!visited[j] && dist[j]==dist[pos]+map[pos][j])
{
if(min_cost[pos]+cost[pos][j]<min_cost[j])
min_cost[j]=min_cost[pos]+cost[pos][j];
}
}
}
cout<<dist[end]<<" "<<min_cost[end]<<endl;
}
int main()
{
int i,j;
int a,b,d,p;
while(cin>>N>>M && (N||M))
{
for(i=1;i<=N;i++)//初始化
for(j=1;j<=N;j++)
{
if(i==j)
{
map[i][j]=0;
cost[i][j]=0;
}
else
{
map[i][j]=INF;
cost[i][j]=INF;
}
}
//(极大的郁闷,开始用注释里面的初始化方法就是Wrong Answer!!!)
//初始化所有点到点的距离为INF,防止有的点对之间不可达
//memset(map,INF,sizeof(map));
//memset(cost,INF,sizeof(cost));
//初始化节点到自身的距离为0
/*for(i=1;i<=N;i++)
{
for(j=1;j<=N;j++)
{
if(i==j)
{
map[i][j]=map[j][i]=0;
cost[i][j]=cost[j][i]=0;
}
}
}
*/
//输入给出的数据
for(i=1;i<=M;i++)
{
cin>>a>>b>>d>>p;
if(d<map[a][b])//注意:过滤掉重边,输入可能包含重边
{
map[a][b]=map[b][a]=d;
cost[a][b]=cost[b][a]=p;
}
}
cin>>start>>end;
Dijkstra();
}
//system("pause");
return 0;
}