-
题目描述:
-
给你n个点,m条无向边,每条边都有长度d和花费p,给你起点s终点t,要求输出起点到终点的最短距离及其花费,如果最短距离有多条路线,则输出花费最少的。
-
输入:
-
输入n,m,点的编号是1~n,然后是m行,每行4个数 a,b,d,p,表示a和b之间有一条边,且其长度为d,花费为p。最后一行是两个数 s,t;起点s,终点t。n和m为0时输入结束。
(1<n<=1000, 0<m<100000, s != t)
-
输出:
-
输出 一行有两个数, 最短距离及其花费。
-
样例输入:
-
3 2 1 2 5 6 2 3 4 5 1 3 0 0
-
样例输出:
-
9 11
- #include <iostream>
- #include <string>
- #include <algorithm>
- #include <memory.h>
- #include <cstdio>
- #include <cstdlib>
- #include <queue>
- #include <vector>
- using namespace std;
- #define MAX 0Xfffffff
- struct Node{
- int p, d;
- int th;
- bool operator<(const Node& node)const{
- if(d==node.d)
- return p<node.p;
- return d<node.d;
- }
- };
- bool visit[1001];
- int mapd[1001][1001];
- int mapp[1001][1001];
- int dis[1001];
- int ps[1001];
- priority_queue<Node> q;
- int main(){
- //freopen("in.txt", "r", stdin);
- int n, m;
- int a, b, d, p;
- while(cin>>n>>m, n+m){
- for(int i=1;i<=n;++i){
- visit[i] = false;
- dis[i] = MAX;
- ps[i] = MAX;
- for(int j=1;j<=n;++j){
- if(i==j){
- mapd[i][j] = mapp[i][j] = 0;
- continue;
- }
- mapd[i][j] = MAX;
- mapp[i][j] = MAX;
- }
- }
- for(int i=0;i<m;++i){
- scanf("%d%d%d%d", &a, &b, &d, &p);
- if(d<mapd[a][b]){
- mapd[a][b] = mapd[b][a] = d;
- mapp[a][b] = mapp[b][a] = p;
- }else if(d==mapd[a][b]&&p<mapp[a][b]){ //这种情况应该考虑进去,否则会出错
- mapp[a][b] = mapp[b][a] = p;
- }
- }
- int s, t;
- cin>>s>>t;
- Node node;
- node.th = s;
- node.d = 0;
- node.p = 0;
- dis[s] = 0;
- visit[s] = true;
- q.push(node);
- while(!q.empty()){
- Node node = q.top();
- q.pop();
- visit[node.th] = true;
- for(int i=1;i<=n;++i){
- if(i!=node.th && mapd[node.th][i]!=MAX && !visit[i]){ //遍历过的结点当然不能再取遍历了
- if(node.d + mapd[node.th][i] < dis[i]){
- dis[i] = node.d + mapd[node.th][i];
- ps[i] = node.p + mapp[node.th][i];
- Node tmp;
- tmp.th = i;
- tmp.d = dis[i];
- tmp.p = ps[i];
- q.push(tmp);
- }else if(node.d + mapd[node.th][i] == dis[i] && node.p + mapp[node.th][i] < ps[i]){
- ps[i] = node.p + mapp[node.th][i];
- Node tmp;
- tmp.d = dis[i];
- tmp.p = ps[i];
- tmp.th = i;
- q.push(tmp);
- }
- }
- }
- }
- printf("%d %d\n", dis[t], ps[t]);
- }
- //fclose(stdin);
- }