题意
考察Dijkstra算法,双重边权。
思路
寻找最优路径并记录(pre),最后后序遍历输出路径。
#pragma GCC optimize(2)
#include"bits/stdc++.h"
using namespace std;
const int maxn = 510;
int G[maxn][maxn]; int G2[maxn][maxn];
int dis[maxn]; int dis2[maxn];
int vis[maxn];
struct Node{
bool operator()(int a,int b){
return dis[a] >= dis[b];
}
};
int n,m,s,d;
int pre[maxn];
void diskj(int startId){
fill(dis,dis+maxn,INT32_MAX); dis[startId] = 0;
fill(dis2,dis2+maxn,INT32_MAX); dis2[startId] = 0;
priority_queue<int,vector<int>,Node> q;
q.push(startId);
for (int i = 0; i < n; ++i) {
int id;
while (true){
if (q.empty()) {
return;
} else if (vis[q.top()]) {
q.pop();
continue;
}
id = q.top(); q.pop(); vis[id] = 1;
break;
}
for (int j = 0; j < n; ++j) {
if (vis[j] || G[id][j] == INT32_MAX)
continue;
int ec = dis[id] + G[j][id],ec2 = dis2[id] + G2[j][id];
if (ec < dis[j]){
dis[j] = ec; dis2[j] = ec2;
q.push(j); pre[j] = id;
} else if (ec == dis[j] && ec2 < dis2[j]){
dis2[j] = ec2;
q.push(j); pre[j] = id;
}
}
}
}
//后序遍历输出从 startId 到 id 的路径
void show(int id,int startId){
if (id == startId) {
printf("%d ",startId);
return;
}
show(pre[id],startId);
printf("%d ",id);
}
int main(){
fill(G[0],G[0]+maxn*maxn,INT32_MAX); fill(G2[0],G2[0]+maxn*maxn,INT32_MAX);
//freopen("input.txt","r",stdin);
cin >> n >> m >> s >> d;
for (int i = 0; i < m; ++i) {
int id1,id2,c1,c2; scanf("%d%d%d%d",&id1,&id2,&c1,&c2);
G[id1][id2] = G[id2][id1] = c1; G2[id1][id2] = G2[id2][id1] = c2;
}
diskj(s);
show(d,s);
printf("%d %d\n",dis[d],dis2[d]);
}
input
4 5 0 3 0 1 1 20 1 3 2 30 0 3 4 10 0 2 2 20 2 3 1 20
ouput
0 2 3 3 40