Heavy Transportation POJ

N个点,M条边,每条边有权值。求一条1号点到N号点的路径,要求使得路径中的边权最小值最大。

Input
多组输入,第一行给一个T。
每一组第一行给两个数n和m。(1 <= n <= 1000)
接下来m行,每行三个数u,v,w代表路径的两个端点与边权。
(1 <= u,v <= n , 0< w <= 1e6)
保证两点间只有一条边,该图为无向图。

Output
第i组数据先输出 “Scenario #i:”
然后输出该路径上的最小边权,外加一个空行。
保证有解

Sample Input
1
3 3
1 2 3
1 3 4
2 3 5

Sample Output
Scenario #1:
4

思路:dist[i]表示从1到i的路径中最大化的最小边权。如果存在一条j->i的边,那么dist[i]=max(dist[i],min(dist[v],dis[i,j]))
要求最大化最小值,所以堆里面的最小值不一定是该点最大化的最小值,只有最大值才是该点确定的最大化最小值,所以必须开大顶堆才可以。

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<queue> 
#include<vector>
#include<utility>
typedef long long ll;
#define pii pair<int,int> 
using namespace std;
const int N=200010;
int n,t;
int h[N],e[N],ne[N],w[N],cnt;
void add(int a,int b,int c)
{
	e[cnt]=b;
	w[cnt]=c;
	ne[cnt]=h[a];
	h[a]=cnt++;
}
int dist[N];

bool st[N];
void dij()
{
	for(int i=1;i<=n;i++) dist[i]=0,st[i]=false;
	dist[1]=0x3f3f3f3f;
	priority_queue<pii,vector<pii>,less<pii> > q;
	q.push(make_pair(dist[1],1)); 
	while(q.size())
	{
		int t=q.top().second;
		q.pop();
		if(st[t]) continue;
		for(int j=h[t];j!=-1;j=ne[j])
		{
			int v=e[j];
			if(dist[v]<min(dist[t],w[j]))
			{
				dist[v]=min(dist[t],w[j]);
				q.push(make_pair(dist[v],v));
			}
		}
		st[t]=1;
	}
	return ;
}
int idx,m;
int main()
{
	scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d",&n,&m);
		cnt=0;
		for(int i=0;i<=n;i++) h[i]=-1;
		for(int i=1;i<=m;i++) 
		{
			int a,b,c;
			scanf("%d%d%d",&a,&b,&c);
			add(a,b,c);add(b,a,c);
		}
		dij();
		printf("Scenario #%d:
%d

",++idx,n==1?0:dist[n]);//注意输出格式
	}
	return 0;
}

原文地址:https://www.cnblogs.com/neflibata/p/12871743.html