题意:n 个点 和 m 条带权边,求点 1 到 n 的最大最小边(即1到n的一条路径上的最小边,所有路径的最小边的最大值);
分析:Dijkstra变形一下,因为是求最大最小边,dis起点设为INF,其余点设为0;
代码:
#include<queue>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int INF = 1E9+7;
const int N = 1000+5;
struct edge{
int to,w,nxt;
}e[N*N];
int head[N],tot;
struct node{
int x,pos;
node(int _x=0,int _pos=0):x(_x),pos(_pos){}
bool operator < (const node& a)const{
return x<a.x;
}
};
void add(int u,int v,int w){
e[tot].to=v;
e[tot].w =w;
e[tot].nxt=head[u];
head[u]=tot++;
}
int n,m,dis[N]; bool vis[N];
void Dij(){
for(int i=0;i<=n;i++){
dis[i]=0,vis[i]=false;
}
priority_queue<node>que;
dis[1]=INF;
que.push(node(INF,1));
while(!que.empty()){
node top=que.top(); que.pop();
int len=top.x,u=top.pos;
if(vis[u]||dis[u]<len) continue;
vis[u]=1;
for(int i=head[u];i!=-1;i=e[i].nxt){
int w=e[i].w,v=e[i].to;
if(dis[v]<min(dis[u],w)){
dis[v]=min(dis[u],w);
que.push(node(dis[v],v));
}
}
}
printf("%d\n\n",dis[n]);
}
int main()
{
int T; scanf("%d",&T);
for(int cas=1;cas<=T;cas++){
memset(head,-1,sizeof(head)),tot=0;
scanf("%d%d",&n,&m);
while(m--){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w),add(v,u,w);
}
printf("Scenario #%d:\n",cas);
Dij();
}
}