Title Link: http://acm.hdu.edu.cn/showproblem.php?pid=3790
This problem is to choose the one that costs the least under the condition of the shortest path, so it needs to update the cost when relaxing. If three points are connected by a line, the first point is also connected with the third point. Because dij always chooses the one that is closest to the far point in the dis array and has not been relaxed when relaxing the edge, so in terms of the shortest path, this The point must be the point in the shortest path, but if the condition of cost is added, the same way to walk 123 miles and save money is to go from 1 to 3 directly. So when we judge if dis[1-3]==dis[1-2-3], we start to judge the cost of them.
AC Code:
#include <bits/stdc++.h> using namespace std; const int maxn = 1e5+10; int n, m, s, t; int d[maxn],p[maxn]; vector<pair<int,int> >E[maxn]; vector<pair<int,int> >Ep[maxn]; void init() { for(int i = 0; i < maxn; i++) d[i] = 1e9; for(int i = 0; i < maxn; i++) E[i].clear(),Ep[i].clear(); } void Dijkstra() { priority_queue<pair<int,int> >Q; Q.push(make_pair(-d[s],s)); while(!Q.empty()) { int now = Q.top().second; Q.pop(); for(int j = 0; j < E[now].size(); j++) { int v = E[now][j].first; if(d[v] > d[now]+E[now][j].second) { d[v] = d[now]+E[now][j].second; p[v] = p[now]+Ep[now][j].second; Q.push(make_pair(-d[v],v)); } else if(d[v] == d[now]+E[now][j].second && p[v] > p[now]+Ep[now][j].second) p[v] = p[now]+Ep[now][j].second; } } } int main() { while(scanf("%d%d",&n,&m),n||m) { init(); int a, b, x, c; for(int i = 0; i < m; i++) { scanf("%d%d%d%d",&a,&b,&x,&c); E[a].push_back(make_pair(b,x)); E[b].push_back(make_pair(a,x)); Ep[a].push_back(make_pair(b,c)); Ep[b].push_back(make_pair(a,c)); } scanf("%d %d",&s, &t); d[s] = 0; p[s] = 0; Dijkstra(); printf("%d %d\n",d[t], p[t]); } return 0; }