Heavy Transportation POJ - 1797
背景
雨果重工很高兴。Cargolifter项目崩溃后,他现在可以扩展业务。但是他需要一个聪明的人,告诉他从客户建造巨型钢起重机的地方到所有街道都可以承载重量的地方是否真的有办法。
幸运的是,他已经制定了一个计划,包括所有街道和桥梁以及所有允许的重量。不幸的是,他不知道如何找到最大重量来告诉他的客户起重机可能会变得很重。但是你当然知道。
问题
系统会为您提供城市规划,由交叉口之间的街道(权重限制)描述,该街道编号为1到n。您的任务是找到从1号交叉口(Hugo的位置)到n号交叉口(客户的位置)可以运输的最大重量。您可以假设至少有一条路径。所有街道均可双向行驶。
Input
第一行包含方案(城市计划)的数量。对于每个城市,第一行给出的是路口交叉口数量n(1 <= n <= 1000)和街道数量m。接下来的m行包含整数的三元组,这些整数指定了道路的起点和终点交叉点以及允许的最大权重,该权重为正且不大于1000000。每对交叉点之间最多有一条街道。
Output
每个方案的输出都以包含“方案#i:”的行开头,其中i是从1开始的方案编号。然后打印一行,其中包含Hugo可以运输给客户的最大允许重量。用空白行终止方案的输出。
Sample Input
1
3 3
1 2 3
1 3 4
2 3 5
Sample Output
Scenario #1:
4
题意:求每条路径中的最短边的最大值
改写d数组的含义: d[i] 代表1到i点的所有边中最小值最大的一个。
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
const int N = 1e6;
int t, n, m, d[1005], head[1005], len, u, v, w;//d[i]为1点到i点路径中的最短边的最大值
bool vis[1005];
struct edge{
int v, w, next;
}e[N];
struct node{
int v, d;
node(int v, int d): v(v), d(d) {
}
bool operator < (const node& W)const {
return d < W.d;//d大的应该先出来
}
};
void add(int u, int v, int w) {
e[len].v = v;
e[len].w = w;
e[len].next = head[u];
head[u] = len++;
}
void dijkstra() {
memset(d, 0, sizeof(d));
memset(vis, false, sizeof(vis));
d[1] = 0x3f3f3f3f;
priority_queue<node> q;
q.push(node(1, d[1]));
while(!q.empty()) {
int u = q.top().v;
q.pop();
if(vis[u]) continue;
vis[u] = true;
for(int j = head[u]; j; j = e[j].next) {
int v = e[j].v;
int w = min(d[u], e[j].w);//看这条边 和之前的最小值谁小
if(d[v] < w) {
d[v] = w;
if(!vis[v]) {
q.push(node(v, d[v]));
}
}
}
}
}
int main() {
scanf("%d", &t);
for(int k = 1; k <= t; k++) {
len = 1;
memset(head, 0, sizeof(head));
scanf("%d%d", &n, &m);
while(m--) {
scanf("%d%d%d", &u, &v, &w);
add(u, v, w);
add(v, u, w);
}
dijkstra();
printf("Scenario #%d:\n%d\n\n", k, d[n]);
}
return 0;
}