POJ 3268
下意识想到了Floyd算法,不过在寻找数据的时候才发现没有仔细分析时间复杂度的弊端(也可能是因为自己这方面的能力弱,所以抵触去分析时间复杂度)
利用刘汝佳的模板,dijkstra是可以满足时间复杂度要求的解法。此外,单源最短路径和单“汇”最短路径其实是对称的问题(正是本题需要dijkstra同时求解的两个问题),对于数据特殊处理即可解决,所以采取的思路是牺牲空间,开对偶的数组来实现这两个问题的同时求解。
#include <iostream>
#include <algorithm>
#include <queue>
#include <string>
#include <vector>
#include <cstdio>
#include <cstring>
#include <map>
using namespace std;
const int maxn= 1005;
struct Edge
{
int f, t, d;
};
struct HeapNode
{
int u, d;
bool operator < (const HeapNode &rhs) const
{
return this->d > rhs.d;
}
};
int n, m, x;
vector<int> G[2][maxn];
vector<Edge> edges[2];
int dis[2][maxn], vis[2][maxn];
void BiAddEdge(int &a, int &b, int &t)
{
edges[0].push_back((Edge){a, b, t});
G[0][a].push_back(edges[0].size()-1);
edges[1].push_back((Edge){b, a, t});
G[1][b].push_back(edges[1].size()-1);
}
void Dijkstra(int s, int id)
{
priority_queue<HeapNode> Q;
memset(dis[id], 0x3f, sizeof(dis[id]));
memset(vis[id], 0, sizeof(vis[id]));
dis[id][s]= 0;
Q.push((HeapNode){s, 0});
while (!Q.empty()){
HeapNode p= Q.top();
Q.pop();
int u= p.u;
if (vis[id][u]){
continue;
}
vis[id][u]= 1;
for (vector<int>::iterator gIter= G[id][u].begin();
G[id][u].end()!= gIter; ++gIter){
Edge &e= edges[id][*gIter];
if (e.d+dis[id][u]< dis[id][e.t]){
dis[id][e.t]= e.d+dis[id][u];
Q.push((HeapNode){e.t, dis[id][e.t]});
}
}
}
}
void Init()
{
for (int i= 1; i<= n; ++i){
G[0][i].clear();
G[1][i].clear();
}
edges[0].clear();
edges[1].clear();
}
int main(int argc, char const *argv[])
{
scanf("%d %d %d", &n, &m, &x);
int a, b, t;
int ans = 0;
Init();
for (int i= 0; i< m; ++i){
scanf("%d %d %d", &a, &b, &t);
BiAddEdge(a, b, t);
}
Dijkstra(x, 0);
Dijkstra(x, 1);
for (int j= 1; j<= n; ++j){
ans= max(ans, dis[0][j]+dis[1][j]);
}
printf("%d\n", ans);
return 0;
}