题目链接:http://poj.org/problem?id=3268
题目大意:有n个位置,m条路,求所有点到某一固定点x往返时间的最大值(有向),从i位置到j位置所需要用的时间
算法:SPFA
思路:2次SPFA,一次正向,第二次反向
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<queue>
using namespace std;
const int inf = 0xfffffff;
queue<int> q;
int head[2][123456];
struct Edge
{
int v, w, next;
}edge[2][168971];
int dis[123456];
int vis[123456];
int tot[2];
int ans[123465];
int n;
void add_edge(int s, int v, int w, int k)
{
edge[k][tot[k]].v = v;
edge[k][tot[k]].w = w;
edge[k][tot[k]].next = head[k][s];
head[k][s] = tot[k] ++;
}
void SPFA(int pos, int k)
{
int i;
for(i = 1; i <= n; i ++)
dis[i] = inf ;
q.push(pos);
vis[pos] = 1;
dis[pos] = 0;
while(!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for(i = head[k][u]; i != -1; i = edge[k][i].next)
{
int e = edge[k][i].v;
if(dis[e] > dis[u] + edge[k][i].w)
{
dis[e] = dis[u] + edge[k][i].w;
if(!vis[e])
q.push(e);
vis[e] = 1;
}
}
}
for(i = 1; i <= n; i ++)
{
// printf("dis[%d] = %d\n", i, dis[i]);
if(i != pos)
ans[i] += dis[i];
}
}
int main()
{
int m, k;
while(scanf("%d%d%d", &n, &m, &k) != EOF)
{
int a, b, c, i;
tot[1] = tot[0] = 0;
memset(head, -1, sizeof(head));
memset(ans, 0, sizeof(ans));
for(i = 1; i <= m; i ++)
{
scanf("%d%d%d", &a, &b, &c);
add_edge(a, b, c, 1);
add_edge(b, a, c, 0);
}
memset(vis, 0, sizeof(vis));
SPFA(k, 0);
memset(vis, 0, sizeof(vis));
SPFA(k, 1);
int minc = -inf;
for(i = 1; i <= n; i ++)
{
if(i != k)
{
if(minc < ans[i])
minc = ans[i];
}
}
printf("%d\n", minc);
}
return 0;
}