甲级1111题,除了繁琐没啥难度,常规模板题
dijkstra的时候维护一个prev前置节点数组,然后用DFS去遍历这个prev,从图中出发的终点开始,起点结束。
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <algorithm>
#include <vector>
#include <stdio.h>
using namespace std;
const int maxnum = 505;
const int INF = 99999;
int N, M, S, E;
int G[maxnum][maxnum];
int T[maxnum][maxnum];
int d[maxnum];
int t[maxnum];
bool viewed[maxnum];
vector<int> prevd[maxnum];
vector<int> prevt[maxnum];
void DijkstraD(int s)
{
fill(d, d + maxnum, INF);
d[s] = 0;
fill(viewed, viewed + maxnum, false);
for (int i = 0; i < N; i++)
{
int u = -1, MIN = INF;
for (int j = 0; j < N; j++)
{
if (viewed[j] == false && d[j] < MIN)
{
u = j;
MIN = d[j];
}
}
if (u == -1) return;
viewed[u] = true;
for (int v = 0; v < N; v++)
{
if (viewed[v] == false && G[u][v] != INF)
{
if (d[u] + G[u][v] < d[v])
{
prevd[v].clear();
prevd[v].push_back(u);
d[v] = d[u] + G[u][v];
}
else if(d[u] + G[u][v] == d[v])
prevd[v].push_back(u);
}
}
}
}
void DijkstraT(int s)
{
fill(t, t + maxnum, INF);
t[s] = 0;
fill(viewed, viewed + maxnum, false);
for (int i = 0; i < N; i++)
{
int u = -1, MIN = INF;
for (int j = 0; j < N; j++)
{
if (viewed[j] == false && t[j] < MIN)
{
u = j;
MIN = t[j];
}
}
if (u == -1) return;
viewed[u] = true;
for (int v = 0; v < N; v++)
{
if (viewed[v] == false && T[u][v] != INF)
{
if (t[u] + T[u][v] < t[v])
{
prevt[v].clear();
prevt[v].push_back(u);
t[v] = t[u] + T[u][v];
}
else if (t[u] + T[u][v] == t[v])
prevt[v].push_back(u);
}
}
}
}
int mintime = INF;
vector<int> tmp;
vector<int> resD;
void DFSd(int v)
{
if (v == S)
{
tmp.push_back(v);
int time = 0,pre,cur;
for (int i = tmp.size() - 1; i >= 1; i--)
{
pre = tmp[i], cur = tmp[i - 1];
time += T[pre][cur];
}
if (time < mintime)
{
resD.clear();
resD = tmp;
mintime = time;
}
tmp.pop_back();
}
tmp.push_back(v);
for (int i = 0; i < prevd[v].size(); i++)
{
DFSd(prevd[v][i]);
}
tmp.pop_back();
}
vector<int> resT;
int minnode = INF;
void DFSt(int v)
{
if (v == S)
{
tmp.push_back(v);
int node = tmp.size();
if (node < minnode)
{
resT.clear();
resT = tmp;
minnode = node;
}
tmp.pop_back();
}
tmp.push_back(v);
for (int i = 0; i < prevt[v].size(); i++)
{
DFSt(prevt[v][i]);
}
tmp.pop_back();
}
int main()
{
cin >> N >> M;
fill(G[0], G[0] + maxnum * maxnum, INF);
fill(T[0], T[0] + maxnum * maxnum, INF);
for (int i = 0; i < M; i++)
{
int a, b, oneway, dis, time;
cin >> a >> b >> oneway >> dis >> time;
if (oneway)//单向
{
G[a][b] = dis;
T[a][b] = time;
}
else
{
G[a][b] = G[b][a] = dis;
T[a][b] = T[b][a] = time;
}
}
cin >> S >> E;
DijkstraD(S);
DijkstraT(S);
DFSd(E);
tmp.clear();
DFSt(E);
if (resD == resT)
{
printf("Distance = %d;", d[E]);
printf(" Time = %d: ",t[E]);
for (int i = resD.size() - 1; i >= 0; --i)
{
if (i == resD.size() - 1) cout << resD[i];
else cout << " -> " << resD[i];
}
}
else
{
printf("Distance = %d: ", d[E]);
for (int i = resD.size() - 1; i >= 0; --i)
{
if (i == resD.size() - 1) cout << resD[i];
else cout << " -> " << resD[i];
}
cout << "\n";
printf("Time = %d: ", t[E]);
for (int i = resT.size() - 1; i >= 0; --i)
{
if (i == resT.size() - 1) cout << resT[i];
else cout << " -> " << resT[i];
}
}
return 0;
}