HDU3790 最短路径问题

来源:互联网 发布:php 返回页面 编辑:程序博客网 时间:2024/05/29 05:03

最短路径问题

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 26688    Accepted Submission(s): 7921


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 21 2 5 62 3 4 51 30 0
 

Sample Output
9 11
 

Source
浙大计算机研究生复试上机考试-2010年

题意:中文题目不解释。

解析:典型最短路径问题,使用Dijstra算法就可搞定。需要注意的是这个题目的条件是两个,首先要保证路径最短,如果路径长度一样,那就要求花费最少。解决这个问题只需要在对路径松弛的时,在路径相等的时候加一个判断花费的条件。具体见代码:

#include <stdio.h>#include <string.h>#include <algorithm>#include <vector>#include <queue>using namespace std;#define INF 100000007#define N 1005typedef long long ll;struct node{int x;ll d, p;bool operator < (const node &a)const{if(d == a.d)return p > a.p;return d > a.d;}};ll dis[N], cost[N];bool vis[N];int n, m;vector<node> V[N];priority_queue<node> Q;void Dijstra(int start){node q, p;for(int i = 0; i <= n; i++){dis[i] = INF;vis[i] = 0;cost[i] = INF;}dis[start] = 0;cost[start] = 0;p.x = start, p.d = 0, p.p = 0;Q.push(p);while(!Q.empty()){p = Q.top();Q.pop();int x = p.x;if(vis[x]) continue;vis[x] = 1;for(int i = 0; i < V[x].size(); i ++){int to = V[x].at(i).x;ll len = V[x].at(i).d;ll cst = V[x].at(i).p;if(dis[to] > dis[x] + len){dis[to] = dis[x] + len;cost[to] = cost[x] + cst;q.x = to, q.d = dis[to], q.p = cost[to];Q.push(q);}else if(dis[to] == dis[x] + len && cost[to] > cost[x] + cst){cost[to] = cost[x] + cst;q.x = to, q.d = dis[to], q.p = cost[to];Q.push(q);}}}}int main(){node q;while(scanf("%d%d", &n, &m) && (n + m)){int a, b, d, p;for(int i = 1; i <= n; i++)V[i].clear();for(int i = 0; i < m; i ++){scanf("%d%d%d%d", &a, &b, &d, &p);q.x = b, q.d = d, q.p = p;V[a].push_back(q);q.x = a;V[b].push_back(q);}scanf("%d%d", &a, &b);Dijstra(a);printf("%lld %lld\n", dis[b], cost[b]);}return 0;}