最短路径问题
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 16613 Accepted Submission(s): 4973
Problem Description 给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
Input 输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
Output 输出 一行有两个数, 最短距离及其花费。
Sample Input
3 2
1 2 5 6
2 3 4 5
1 3
0 0
Sample Output
9 11
Source 浙大计算机研究生复试上机考试-2010年 还记得第一次看这道题是acm队员选拔的时候,那时候看的云里雾里,更不知道什么是dijkstra,prim,kruskal等等... 到现在三个月过去了,能靠自己ac这道题,也是进步。 废话不说,这道题就是dijkstra最短路径问题。这道题也要注意重边的问题。判断一下就行。 具体看代码:
#include <stdio.h>
#include <queue>
#include <string.h>
using namespace std;
int n,m,cost[1005][1005],len[1005][1005],vis[1005];//cost存贮花费,len存贮长度,vis标记
struct node
{
int pay,l,pos;
friend bool operator< (const node a,const node b)//根据题意要求,如果路径相等按照花费排序
{
if(a.l>b.l) return true;
if(b.l==a.l&&a.pay>b.pay) return true;
return false;
}
};
priority_queue<node>s;
void dijkstra(int star,int end)
{
node temp,x;
temp.pos=star,temp.l=0,temp.pay=0;
s.push(temp);
while(!s.empty())
{
temp=s.top();
s.pop();
star=temp.pos;
if(star==end)
break;
x=temp;
for(int i=1;i<=n;i++)//从1开始
{
if(!vis[i]&&len[star][i]<1000000)
{
temp.l+=len[star][i];
temp.pay+=cost[star][i];
temp.pos=i;
s.push(temp);
vis[star]=1;
}
temp=x;
}
}
printf("%d %d\n",temp.l,temp.pay);
}
int main()
{
int star,end;
while(scanf("%d %d",&n,&m)!=EOF,(m||n))
{
memset(vis,0,sizeof(vis));
memset(cost,100,sizeof(cost));
memset(len,100,sizeof(len));
for(int i=0;i<m;i++)
{
int a,b,d,p;
scanf("%d %d %d %d",&a,&b,&d,&p);
if(d<len[a][b]||(d==len[a][b]&&p<cost[a][b]))//避免重边,判断一下
len[a][b]=len[b][a]=d,cost[a][b]=cost[b][a]=p;;
}
scanf("%d %d",&star,&end);
dijkstra(star,end);
while(!s.empty())
s.pop();
}
return 0;
}