大意略。
思路: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;
}