题目 http://acm.hdu.edu.cn/showproblem.php?pid=3790
看这个题目要求最短路 ,而且如果最短路有多条 ,找出一条费用最小的。
所以我们用一个数组来记录 边及没条边的费用。。。。
然后我们按照求最短路的方法来求, 就是在更新每条边的时候,顺便来找出路径长度相同,但是费用小的。。。
具体代码
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
struct node{
int value; ///记录边的值
int edg; ///边的大小
};
int n,m,s,t; ///s是起点 t是终点
#define INF 999999
node a[1002][1002];
bool v[1002]; ///标记顶点
node dis[1002]; ///每个顶点到源点的距离和值哦
void Dijkstra()
{
int k,min;
memset(v,false,sizeof(v)); ///标记顶点
for(int i=0;i<n;i++)
{
dis[i].edg=a[s][i].edg;
dis[i].value=a[s][i].value;
}
dis[s].edg=0;
dis[s].value=0;
for(int i=0;i<n;i++)
{
min=INF;
for(int j=0;j<n;j++)
{
if(!v[j]&&dis[j].edg<min) ///每次找出最短的边
{
min=dis[j].edg;
k=j;
}
}
v[k]=true;
for(int j=0;j<n;j++)
{
if(!v[j]&&dis[k].edg+a[k][j].edg<dis[j].edg) ///更新每个顶点到源点距离
{
dis[j].edg=dis[k].edg+a[k][j].edg;
dis[j].value=dis[k].value+a[k][j].value;
}
else if(!v[j]&&dis[k].edg+a[k][j].edg==dis[j].edg)///距离相同 找费用最小的
{
if(dis[j].value>dis[k].value+a[k][j].value)
{
dis[j].value=dis[k].value+a[k][j].value;///更新费用
}
}
}
}
printf("%d %d\n",dis[t-1].edg,dis[t-1].value); ///同理输出是注意
}
int main()
{
int i,j,k,p;
while(cin>>n>>m,n||m)
{
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
{
a[i][j].value=INF;
a[i][j].edg=INF;
}
}
while(m--)
{
scanf("%d %d %d %d",&i,&j,&k,&p);
i=i-1;j=j-1; ///如果是从0 开始的要小心
if(a[i][j].edg>k)
{
a[i][j].edg=a[j][i].edg=k;
a[i][j].value=a[j][i].value=p;
}
}
scanf("%d %d",&s,&t);
s=s-1; ///注意一下 我是从0开始的。。
Dijkstra();
}
return 0;
}