| |||
|
样例输入 Sample Input
4
1 2 30
1 3 20
2 3 25
3 4 30
2 4 20
0 0 0
样例输出 Sample Output
30
25
25
注释 Hint | ||
对于样例数据: 小杉最多能够在人品为30的情况下到达小房间2(1->2) 小杉最多能够在人品为25的情况下到达小房间3(1->2->3) 小杉最多能够在人品为25的情况下到达小房间4(1->2->3->4) |
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int N;
struct Edge
{
int u, v, d; Edge *next; Edge() {}
Edge(int v, int d, Edge *next):
v(v), d(d), next(next){}
}*edge[4000];
int dist[4005], S, T;
int queue[1999010];
bool Vst[4005];
void init_file()
{
freopen("prison.dat", "r", stdin);
freopen("prison.out", "w", stdout);
}
inline void Ins(int u, int v, int d)
{
edge[u] = new Edge(v, d, edge[u]);
//edge[v] = new Edge(u, d, edge[v]);
return;
}
void read_data()
{
int x, y, z;
scanf("%d", &N);
while(scanf("%d%d%d", &x, &y, &z) == 3)
{
if (x == 0 && y == 0 && z == 0) break;
Ins(x, y, z);
}
S = 1;
}
inline void Spfa()
{
static int f = 0, r = 0, u, v; static Edge *p;
memset(dist, 0, sizeof dist);
for (dist[queue[r++] = S] = 999999, Vst[S] = 1; f < r;)
for (p = edge[u = queue[f++]], Vst[u] = 0; p; p = p -> next)
{
int k = min(dist[u], p -> d);
if (dist[v = p -> v] < k)
{
dist[v] = k;
if (!Vst[v]) Vst[queue[r++] = v] = 1;
}
}
return;
}
void work()
{
for(int i = 2; i <= N; i++)
{
printf("%d\n", dist[i]);
}
}
int main()
{
init_file();
read_data();
Spfa();
work();
return 0;
}
这个题就是改一下SPFA 很不错的一道题
松弛的时候用min(dist[u], p -> d)来松弛dist[v]