最小花费最短路

【题目描述】:

给你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时输入结束。

【输出描述】:

输出一行有两个数, 最短距离及其花费。

【样例输入】:

3 2
1 2 5 6
2 3 4 5
1 3
0 0

【样例输出】:

9 11

【时间限制、数据范围及描述】:

时间:1s 空间:128M

对于 30%的数据:1<n<=100

对于100%的数据:1<n<=1000; 0<m<100000; s != t; 1<=d,p<=1000

数据组数<=5,注意卡常;

 

分析:

本题显然是一道最短路,但是注意在最短路的前提下在进行一次贪心,求出最小花费。

 

CODE:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <cmath>
 4 #include <iostream>
 5 #include <algorithm>
 6 #include <queue>
 7 using namespace std;
 8 const int M=1000005;
 9 const int oo=1<<30;
10 int n,m,s,t;
11 int next[M],head[M],to[M],adj[M],val[M];
12 int dist[M],ans[M];
13 struct node{
14     int id,d,v;
15     bool operator> (const node b) const {return d>b.d;}
16 }a[M];
17 priority_queue <node,vector<node>,greater<node> > Q;
18 int tot;
19 inline int get(){
20     char c=getchar();
21     int res=0;
22     while (c<'0'||c>'9') c=getchar();
23     while (c>='0'&&c<='9'){
24         res=(res<<3)+(res<<1)+c-'0';
25         c=getchar();
26     }
27     return res;
28 }
29 void add(int u,int v,int w,int p){
30     next[++tot]=head[u];
31     head[u]=tot;
32     to[tot]=v;
33     adj[tot]=w;
34     val[tot]=p;
35     return;
36 }
37 void dijkstra(){
38     for (int i=1;i<=n;i++) {dist[i]=oo;ans[i]=oo;}
39     dist[s]=0;
40     ans[s]=0;
41     Q.push((node){s,0,0});
42     while (!Q.empty()){
43         node x=Q.top(); 
44         Q.pop();
45         for (int i=head[x.id];i;i=next[i])
46             if (x.d+adj[i]<dist[to[i]]||(x.d+adj[i]==dist[to[i]]&&ans[to[i]]>x.v+val[i])){
47                 dist[to[i]]=x.d+adj[i];
48                 ans[to[i]]=x.v+val[i];
49                 Q.push((node){to[i],dist[to[i]],ans[to[i]]});
50             }
51     }
52     return;
53 }
54 int main(){
55     while (1){
56         n=get(),m=get();
57         if (n==0&&m==0) break;
58         memset(head,0,sizeof(head));
59         for (int i=1;i<=m;i++){
60             int u,v,w,p;
61             u=get(),v=get(),w=get(),p=get();
62             add(u,v,w,p);
63             add(v,u,w,p);
64         }
65         s=get(),t=get();
66         while (!Q.empty()) Q.pop();
67         memset(dist,0,sizeof(dist));
68         memset(ans,0,sizeof(ans));
69         dijkstra();
70         cout<<dist[t]<<" "<<ans[t]<<endl;
71     }
72     return 0;
73 }

 

posted @ 2019-07-02 12:56  Sword_Art_Online  阅读(360)  评论(0编辑  收藏  举报