題意:有n個農場,每個農場有一頭牛。每個農場都有單向的通道到下一個農場。選擇其中一個農場作爲開party的農場。他們去了還得回來。每頭牛都會選擇耗時最短的方案,問這些牛之中,最長的時間是多少。
就是求最短路,不過需要注意的是,數據量有點大。dijkstra 的時間複雜度要比floyd下,應優先考慮。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 1000 + 5;
const int inf = 1e9 + 10;
int n, x, m;
int d[maxn], dback[maxn], G[maxn][maxn];
bool vis[maxn];
void init()
{
for(int i = 0; i <= n; i++)
for(int j = 0; j <= n; j++)
{
if(i != j) G[i][j] = inf;
else G[i][j] = 0;
}
memset(vis, 0, sizeof(vis));
}
int dijkstra()
{
for(int i = 1; i <= n; i++)
{
d[i] = G[x][i];
dback[i] = G[i][x];
}
while(true)
{
int v = -1;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (v == -1 || d[j] < d[v]))
{
v = j;
}
}
if(v == -1) break;
vis[v] = 1;
for(int j = 1; j <= n; j++)
{
d[j] = min(d[j], d[v] + G[v][j]);
}
}
memset(vis, 0, sizeof(vis));
while(true)
{
int v = -1;
for(int j = 1; j <= n; j++)
{
if(!vis[j] && (v == -1 || dback[j] < dback[v]))
{
v = j;
}
}
if(v == -1) break;
vis[v] = 1;
for(int j = 1; j <= n; j++)
{
dback[j] = min(dback[j], dback[v] + G[j][v]);
}
}
int ret = 0;
for(int i = 1; i <= n; i++)
ret = max(ret, d[i] + dback[i]);
return ret;
}
int main()
{
while(scanf("%d%d", &n, &m) == 2 && (m || n))
{
init();
scanf("%d", &x);
for(int i = 0; i < m; i++)
{
int t1, t2, c;
scanf("%d%d%d", &t1, &t2, &c);
G[t1][t2] = c;
}
printf("%d\n", dijkstra());
}
return 0;
}