题目
分析
先按距离求出最短路,再在最短路中找花费最小的路.
引申:多权最短路,在处理好主权的情况下,处理副权。
#include<iostream> #include<cstdio> #include<cmath> #include<queue> #include<cstring> #include<algorithm> #define lson x<<1 #define rson x<<1|1 #define ll long long #define rint register int #define mid ((L + R) >> 1) using namespace std; template <typename xxx> inline void read(xxx &x) { char c = getchar(),f = 1;x = 0; for(;c ^ '-' && !isdigit(c);c = getchar()); if(c == '-') c = getchar(),f = -1; for(;isdigit(c);c = getchar()) x = (x<<1) + (x<<3) + (c ^ '0'); x *= f; } template<typename xxx>void print(xxx x) { if(x<0){putchar('-');x=-x;} if(x>9) print(x/10); putchar(x%10+'0'); } const int maxn = 100010; const int inf = 0x7fffffff; const int mod = 1e9 + 7; struct edge{ int to,last,d,p; }e[maxn<<1]; int head[maxn],tot; inline void add(int from,int to,int d,int p) { ++tot; e[tot].d = d; e[tot].p = p; e[tot].to = to; e[tot].last = head[from]; head[from] = tot; } int n,m; queue<int>q; int dis[maxn],vis[maxn],num[maxn]; inline void spfa(int ks) { for(rint i = 0;i <= n; ++i) dis[i] = inf,vis[i] = 0,num[i] = 0; q.push(ks);dis[ks] = 0;num[ks] = 1; while(q.size()) { int x = q.front();q.pop();vis[x] = 0; for(rint i = head[x]; i; i = e[i].last) { if(dis[e[i].to] > dis[x] + e[i].d) { dis[e[i].to] = dis[x] + e[i].d; if(!vis[e[i].to]) { num[e[i].to] = 1; vis[e[i].to] = 1; q.push(e[i].to); } } else if(dis[e[i].to] == dis[x] + e[i].d) ++num[e[i].to]; } } } int cost[maxn]; inline void ddfs(int ks) { for(rint i = 0;i <= n; ++i) vis[i] = 0,cost[i] = inf; q.push(ks);cost[ks] = 0; while(q.size()) { int x = q.front();q.pop();vis[x] = 0; for(rint i = head[x]; i; i = e[i].last) { if(dis[e[i].to] == dis[x] + e[i].d) { if(cost[e[i].to] > cost[x] + e[i].p) { cost[e[i].to] = cost[x] + e[i].p; if(!vis[e[i].to]) { vis[e[i].to] = 1; q.push(e[i].to); } } } } } } int main() { while(1) { tot = 0; memset(head,0,sizeof(head)); read(n);read(m); if(!n && !m ) break; for(rint i = 1;i <= m; ++i) { int a,b,c,d; read(a);read(b);read(c);read(d); if(a == b) continue; add(a,b,c,d);add(b,a,c,d); } int s,t; read(s);read(t); spfa(s);ddfs(s); print(dis[t]),putchar(' '),print(cost[t]),putchar('\n'); } return 0; } /* */