题目链接:http://poj.org/problem?id=3268
大意:有n个牧场,编号1到n,每个牧场有一头奶牛。现在所有奶牛要到编号为x的牧场聚会,路径是单向的,奶牛都很聪明,只走最短路径,问哪头奶牛来回走的路径之和最大,输出这个最大值。
思路:建立两个邻接表(一个出边表,一个入边表),然后分别对两个邻接表使用一次SPFA,得到的路径长度分别存到dist_o[]和dist_i[]。dist_o + dist_i的最大值就是问题结果。
代码
PS:第一次写SPFA,做题时建邻接表有个指针搞错了找了半天bug,操蛋。。代码也写的很糟糕。以后要多写多练
#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
using namespace std;
#define N 1000
#define INF 1000000000
int vis_i[N + 5], dist_i[N + 5], vis_o[N + 5], dist_o[N + 5];
int n, m;
struct node
{
int to, val;
node * next;
};
node * e_i[N + 5];
node * e_o[N + 5];
void INIT(int v)
{
for (int i = 1; i <= n; i++)
{
if (v == i)
{
dist_i[i] = dist_o[i] = 0;
}
else
{
dist_i[i] = dist_o[i] = INF;
}
}
}
void SPFA_i(int v)
{
queue<int> q;
q.push(v);
while (!q.empty())
{
int a = q.front();
q.pop();
vis_i[a] = 0;
node * p = e_i[a];
//cout << a;
while (p)
{
//cout << " " << p->to;
if (dist_i[a] < INF && dist_i[a] + p->val < dist_i[p->to])
{
dist_i[p->to] = dist_i[a] + p->val;
if (!vis_i[p->to])
{
vis_i[p->to] = 1;
q.push(p->to);
}
}
p = p->next;
}
//cout << endl;
}
}
void SPFA_o(int v)
{
queue<int> q;
q.push(v);
while (!q.empty())
{
int a = q.front();
q.pop();
vis_o[a] = 0;
node * p = e_o[a];
//cout << a;
while (p)
{
//cout << " " << p->to;
if (dist_o[a] < INF && dist_o[a] + p->val < dist_o[p->to])
{
dist_o[p->to] = dist_o[a] + p->val;
if (!vis_o[p->to])
{
vis_o[p->to] = 1;
q.push(p->to);
}
}
p = p->next;
}
//cout << endl;
}
}
int main()
{
int x;
while (cin >> n >> m >> x)
{
for (int i = 0; i <= N; i++)
{
e_i[i] = e_o[i] = NULL;
}
node * p;
for (int i = 1; i <= m; i++)
{
int a, b, t;
scanf("%d %d %d",&a, &b, &t);
p = new node;
p->to = a;
p->val = t;
p->next = NULL;
if (e_i[b] == NULL)
e_i[b] = p;
else
{
p->next = e_i[b];
e_i[b] = p;
}
p = new node;
p->to = b;
p->val = t;
p->next = NULL;
if (e_o[a] == NULL)
e_o[a] = p;
else
{
p->next = e_o[a];
e_o[a] = p;
}
}
INIT(x);
SPFA_i(x);
SPFA_o(x);
int ans = 0;
for (int i = 1; i <=n; i++)
{
dist_i[i] += dist_o[i];
}
sort(dist_i + 1, dist_i + n + 1);
cout << dist_i[n] << endl;
}
return 0;
}