大意略。
思路:Dijkstra预处理起点到任意一点的距离,终点到任意一点的距离,然后通过枚举商业路线确定最优路径,输出通过递归来实现即可。
WA了很多次,Uva论坛里的测试数据我全过了,还是不知道哪里错了。
求测试数据,别复制代码。
#include <iostream> #include <cstdlib> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <vector> #include <queue> #include <stack> using namespace std; const int maxn = 10010; const int INF = 0x3f3f3f3f; stack<int> S; typedef pair<int, int> pii; priority_queue<pii, vector<pii>, greater<pii> > q; struct Edge { int v, w; int next; }edge[maxn*4]; int cnt; int first[maxn]; int fa_1[maxn], fa_2[maxn]; int d[maxn], g[maxn]; int n, s, e, m, k; int su, sv; void init() { while(!S.empty()) S.pop(); cnt = 0; memset(first, -1, sizeof(first)); memset(fa_1, -1, sizeof(fa_1)); memset(fa_2, -1, sizeof(fa_2)); } void read_graph(int u, int v, int w) { edge[cnt].v = v, edge[cnt].w = w; edge[cnt].next = first[u], first[u] = cnt++; } void Dijkstra_1(int src, int end) { while(!q.empty()) q.pop(); for(int i = 1; i <= n; i++) d[i] = (i == src) ? 0 : INF; q.push(make_pair(d[src], src)); while(!q.empty()) { pii u = q.top(); q.pop(); int x = u.second; if(u.first != d[x]) continue; for(int e = first[x]; e != -1; e = edge[e].next) { int v = edge[e].v, w = edge[e].w; if(d[v] > d[x] + w) { fa_1[v] = x; d[v] = d[x] + w; q.push(make_pair(d[v], v)); } } } } void Dijkstra_2(int src, int end) { while(!q.empty()) q.pop(); for(int i = 1; i <= n; i++) g[i] = (i == src) ? 0 : INF; q.push(make_pair(g[src], src)); while(!q.empty()) { pii u = q.top(); q.pop(); int x = u.second; if(u.first != g[x]) continue; for(int e = first[x]; e != -1; e = edge[e].next) { int v = edge[e].v, w = edge[e].w; if(g[v] > g[x] + w) { fa_2[v] = x; g[v] = g[x] + w; q.push(make_pair(g[v], v)); } } } } void read_case() { init(); scanf("%d", &m); while(m--) { int u, v, w; scanf("%d%d%d", &u, &v, &w); read_graph(u, v, w); read_graph(v, u, w); } } void print_1(int x) { if(fa_1[x] == -1) { printf("%d", x); return; } print_1(fa_1[x]); printf(" %d", x); } void print2(int x) { if(fa_2[x] == -1) { S.push(x); return ;} print2(fa_2[x]); S.push(x); } void print_2(int sv) { print2(sv); while(!S.empty()) { printf(" %d", S.top()); S.pop(); } } void solve() { read_case(); Dijkstra_1(s, e); Dijkstra_2(e, s); scanf("%d", &k); int ans = d[e], found = 0; for(int i = 1; i <= k; i++) { int u, v, w; scanf("%d%d%d", &u, &v, &w); if(d[u] + g[v] + w < ans) { found = 1; ans = d[u] + g[v] + w; su = u, sv = v; } if(d[v] + g[u] + w < ans) { found = 1; ans = d[v] + g[u] + w; su = v, sv = u; } } if(!found) { print_1(e); printf("\n"); printf("Ticket Not Used\n"); } else { print_1(su), print_2(sv); printf("\n"); printf("%d\n", su); } printf("%d\n", ans); } int main() { int times = 0; while(~scanf("%d%d%d", &n, &s, &e)) { if(times) { printf("\n"); times++; } solve(); } return 0; }