ACM程序设计选修课——Problem F:(ds:图)旅游规划(优先队列+SPFA)

来源:互联网 发布:怎么能成为淘宝客 编辑:程序博客网 时间:2024/05/17 01:32

问题 F: (ds:图)旅游规划

时间限制: 1 Sec  内存限制: 128 MB
提交: 14  解决: 4

题目描述

有了一张自驾旅游路线图,你会知道城市间的高速公路长度、以及该公路要收取的过路费。现在需要你写一个程序,帮助前来咨询的游客找一条出发地和目的地之间的最短路径。如果有若干条路径都是最短的,那么需要输出最便宜的一条路径。

输入

第一行为整数T,表示有T个case(测试实例)。

接下来每个case包含:

第1行给出4个正整数N、M、S、D,其中N(2<=N<=500)是城市的个数,顺便假设城市的编号为0~(N-1);M是高速公路的条数;S是出发地的城市编号;D是目的地的城市编号。随后的M行中,每行给出一条高速公路的信息,分别是:城市1、城市2、高速公路长度、收费额,中间用空格分开,数字均为整数且不超过500。输入保证解的存在。

输出

在一行里输出路径的长度和收费总额,数字间以空格分隔,输出结尾不能有多余空格。

样例输入

24 5 0 30 1 1 201 3 2 300 3 4 100 2 2 202 3 1 202 1 0 11 0 2 3

样例输出

3 402 3

苦于寻找如何对两个边权进行最短路的计算,无数次WA后总算是知道了。思路:首先正常合并当前边,然后若临时距离等于永久距离之和,则比较费用,若费用小则将费用变化一下。另外一个好处就是由于是搜索全部关联边,因此不用担心重边的问题

代码:

#include<iostream>#include<algorithm>#include<cstdlib>#include<sstream>#include<cstring>#include<cstdio>#include<string>#include<deque>#include<stack>#include<cmath>#include<queue>#include<set>#include<map>#define INF 0x3f3f3f3f#define MM(x) memset(x,0,sizeof(x))using namespace std;typedef long long LL;struct info{    int dx;    int money;}; info d[550];vector<pair<int,info> >que[550]; int main(void){      int tcase;    int n,m,i,j,x,y,z,s,t,des;    scanf("%d",&tcase);    while (tcase--)    {        for (i=0; i<550; i++)            que[i].clear();        memset(d,INF,sizeof(d));        scanf("%d%d%d%d",&n,&m,&s,&des);            info one;        for (i=0; i<m; i++)        {            scanf("%d%d%d%d",&x,&y,&one.dx,&one.money);            que[x].push_back(make_pair(y,one));            que[y].push_back(make_pair(x,one));        }        priority_queue<pair<int,int> >Q;        while (!Q.empty())            Q.pop();          d[s].dx=0;        d[s].money=0;        Q.push(make_pair(-d[s].dx,s));        while (!Q.empty())        {            int now=Q.top().second;            Q.pop();            for (i=0; i<que[now].size(); i++)            {                int v=que[now][i].first;                if(d[v].dx>d[now].dx+que[now][i].second.dx)                {                    d[v].dx   =d[now].dx   +que[now][i].second.dx;                    d[v].money=d[now].money+que[now][i].second.money;                    Q.push(make_pair(-d[v].dx,v));                }                else if(d[v].dx==d[now].dx+que[now][i].second.dx&&d[v].money>d[now].money+que[now][i].second.money)                d[v].money=d[now].money+que[now][i].second.money;            }        }           printf("%d %d\n",d[des].dx,d[des].money);    }    return 0;}

0 0
原创粉丝点击