题目
输入样例1:
10 15
0 1 0 1 1
8 0 0 1 1
4 8 1 1 1
5 4 0 2 3
5 9 1 1 4
0 6 0 1 1
7 3 1 1 2
8 3 1 1 2
2 5 0 2 2
2 1 1 1 1
1 5 0 1 3
1 4 0 1 1
9 7 1 1 3
3 1 0 2 5
6 3 1 2 1
5 3
输出样例1:
Time = 6: 5 => 4 => 8 => 3
Distance = 3: 5 => 1 => 3
输入样例2:
7 9
0 4 1 1 1
1 6 1 3 1
2 6 1 1 1
2 5 1 2 2
3 0 0 1 1
3 1 1 3 1
3 2 1 2 1
4 5 0 2 2
6 5 1 2 1
3 5
输出样例2:
Time = 3; Distance = 4: 3 => 2 => 5
思路
两种路径,两次狄杰斯特拉就可以了。
代码
#include <cstdio>
#include <queue>
#include <map>
#include <cstring>
#include <set>
#include <stack>
using namespace std;
typedef pair<int, int> PII;
const int maxn = 505;
struct Edge{
int to, l, t, next;
}edge[maxn*maxn];
int tot = -1;
int head[maxn*maxn];
void add(int u, int v, int l, int t) {
++tot;
edge[tot].to = v;
edge[tot].l = l;
edge[tot].t = t;
edge[tot].next = head[u];
head[u] = tot;
}
int dist[maxn], tme[maxn];
int pathd[maxn], patht[maxn];
int cnt[maxn], lenth[maxn];
bool operator<(const PII& a, const PII& b) {
return a.second > b.second;
}
int s, d;
priority_queue<PII> que;
void dij1() {
memset(dist, 0x3f, sizeof(dist));
memset(cnt, 0, sizeof(cnt));
set<int> vis;
dist[s] = 0;
cnt[s] = 1;
que.push({s, 0});
while(que.size()) {
auto tmp = que.top(); que.pop();
if(vis.count(tmp.first)) continue;
vis.insert(tmp.first);
for(int i = head[tmp.first]; i != -1; i = edge[i].next) {
int tl = edge[i].l + dist[tmp.first];
if(tl < dist[edge[i].to]) {
dist[edge[i].to] = tl;
pathd[edge[i].to] = tmp.first;
cnt[edge[i].to] = cnt[tmp.first]+1;
que.push({edge[i].to, tl});
}
else if(tl == dist[edge[i].to] && cnt[edge[i].to]>cnt[tmp.first]+1) {
cnt[edge[i].to] = cnt[tmp.first]+1;
pathd[edge[i].to] = tmp.first;
que.push({edge[i].to, tl});
}
}
}
}
void dij2() {
memset(tme, 0x3f, sizeof(tme));
memset(lenth, 0x3f, sizeof(lenth));
set<int> vis;
tme[s] = 0;
lenth[s] = 0;
que.push({s, 0});
while(que.size()) {
auto tmp = que.top(); que.pop();
if(vis.count(tmp.first)) continue;
vis.insert(tmp.first);
for(int i = head[tmp.first]; i != -1; i = edge[i].next) {
int tl = edge[i].t + tme[tmp.first];
if(tl < tme[edge[i].to]) {
tme[edge[i].to] = tl;
patht[edge[i].to] = tmp.first;
lenth[edge[i].to] = lenth[tmp.first]+edge[i].l;
que.push({edge[i].to, tl});
}
else if(tl == tme[edge[i].to] && lenth[edge[i].to]>lenth[tmp.first]+edge[i].l) {
lenth[edge[i].to]=lenth[tmp.first]+edge[i].l;
patht[edge[i].to] = tmp.first;
que.push({edge[i].to, tl});
}
}
}
}
int main(void)
{
// freopen("in.txt", "r", stdin);
int n, m;
scanf("%d%d", &n, &m);
for(int i = 0; i < n; ++i) {
head[i] = pathd[i] = patht[i] = -1;
}
int u, v, o, l, t;
while(m--) {
scanf("%d%d%d%d%d", &u, &v, &o, &l, &t);
add(u, v, l, t);
if(!o)
add(v, u, l, t);
}
scanf("%d%d", &s, &d);
stack<int> ansDis, ansTim;
dij1(); dij2();
ansDis.push(d);
int i = pathd[d];
while(i != -1) {
ansDis.push(i);
i = pathd[i];
}
ansTim.push(d);
i = patht[d];
while(i != -1) {
ansTim.push(i);
i = patht[i];
}
if(ansDis == ansTim) {
printf("Time = %d; Distance = %d:", tme[d], dist[d]);
printf(" %d", ansDis.top()); ansDis.pop();
while(ansDis.size()) {
printf(" => %d", ansDis.top()); ansDis.pop();
}
}
else {
printf("Time = %d:", tme[d]);
printf(" %d", ansTim.top()); ansTim.pop();
while(ansTim.size()) {
printf(" => %d", ansTim.top()); ansTim.pop();
}
printf("\nDistance = %d:", dist[d]);
printf(" %d", ansDis.top()); ansDis.pop();
while(ansDis.size()) {
printf(" => %d", ansDis.top()); ansDis.pop();
}
}
return 0;
}