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;
}