题意:
思路:单源最短路问题,Dijkstra算法搞定就可以了,因为要找出最便宜的最短路,所以需要在更新最短距离的时候加一个条件(即当最短距离相等的时候,如果该路径的花费更小,就更新最小花费)就可以了。之前自己学的最短路的水平也就仅限于模板题的水平,现在可以在条件上稍微加一些变化,做了数据结构的作业,顺便加深了自己对最短路(Dijkstra)算法的理解。
题目所给样例的示意图(数据放在了代码的后边):
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <queue> 3 #include <cstdio> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstring> 7 #include <queue> 8 #include <vector> 9 #define INF 0x3f3f3f3f 10 #define FRE() freopen("in.txt","r",stdin) 11 12 using namespace std; 13 typedef long long ll; 14 typedef pair<int,int> P;//first是距离,second是点的编号 15 const int maxn = 1000; 16 struct Edge{ 17 int to,c,d; 18 Edge(int t,int cost,int dis):to(t),c(cost),d(dis){} 19 }; 20 vector<Edge> G[maxn]; 21 priority_queue<P, vector<P>, greater<P> > que; 22 int dist[maxn],cost[maxn]; 23 int n,m,st,en; 24 25 26 void init(){ 27 int s,e,d,c; 28 scanf("%d%d%d%d",&n,&m,&st,&en); 29 for(int i = 0; i<m; i++){ 30 scanf("%d%d%d%d",&s,&e,&d,&c); 31 G[s].push_back(Edge(e,c,d)); 32 G[e].push_back(Edge(s,c,d)); 33 } 34 for(int i = 0; i<n; i++){ 35 dist[i] = INF; 36 cost[i] = INF; 37 } 38 } 39 40 int main(){ 41 //FRE(); 42 init(); 43 dist[st] = 0; 44 cost[st] = 0; 45 que.push(P(0,st));//指的是当前点的最短距离 46 while(que.size()){ 47 P p = que.top(); 48 que.pop(); 49 int v = p.second;//当前的点 50 if(p.first > dist[v])continue; 51 //cout<<"v: "<<v; 52 for(int i = 0; i<G[v].size(); i++){ 53 Edge e = G[v][i];//当最短距离相等的时候而花费更小的时候,更新最短距离的花费 54 if((dist[e.to] > dist[v]+e.d)||(dist[e.to] == dist[v]+e.d && cost[e.to] > cost[v]+e.c)){ 55 dist[e.to] = dist[v]+e.d; 56 cost[e.to] = cost[v]+e.c; 57 //cout<<" cost: "<<cost[e.to]; 58 que.push(P(dist[e.to], e.to)); 59 } 60 //cout<<" "<<dist[e.to]; 61 } 62 //cout<<endl; 63 } 64 printf("%d %d ",dist[en],cost[en]); 65 return 0; 66 } 67 /* 68 样例输入: 69 4 5 0 3 70 0 1 1 20 71 1 3 2 30 72 0 3 4 10 73 0 2 2 20 74 2 3 1 20 75 样例输出: 76 3 40 77 */