poj1797(dijstra变形,求最小边的最大值)
Posted Frank__Chen
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了poj1797(dijstra变形,求最小边的最大值)相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/POJ-1797
题意:n个点,m条带权边,求点1到点n的所有路径中最小边的最大值。
思路:
和poj2253一样,只不过那题n<=200,可以用floyd,而这题floyd会TLE,所以用dijkstra来做。
提一下floyd的做法,用dp[i][j]表示i到j的所有路径中最小边的最大值,那么转移方程是: dp[i][j]=max(dp[i][j] , min(dp[i][k] , dp[k][j]) )。
dijkstra的做法也是一样的,修改dis数组的定义,即dis[i][j]表示i到j的路径中最小边的最大值,那么松弛操作就是:dis[j]=max(dis[j] , min(dis[i] , e[i][j]) )。优先队列采用降序队列,因为是求最大值,还有dis数组初始化-inf,dis[1]=inf。
AC代码:
#include<cstdio> #include<queue> #include<algorithm> using namespace std; const int maxn=1005; const int inf=0x3f3f3f3f; int T,n,m,cas,e[maxn][maxn],vis[maxn],dis[maxn]; typedef pair<int,int> PII; priority_queue<PII> pq; void dijkstra(){ int num=0; for(int i=1;i<=n;++i) vis[i]=0,dis[i]=-inf; dis[1]=inf; pq.push(make_pair(inf,1)); while(!pq.empty()&&num<=n){ int u=pq.top().second; pq.pop(); if(vis[u]) continue; vis[u]=1; ++num; for(int i=1;i<=n;++i) if(e[u][i]!=-1&&!vis[i]){ dis[i]=max(dis[i],min(dis[u],e[u][i])); pq.push(make_pair(dis[i],i)); } } } int main(){ scanf("%d",&T); while(T--){ scanf("%d%d",&n,&m); for(int i=1;i<=n;++i) for(int j=1;j<=n;++j) e[i][j]=-1; for(int i=1;i<=m;++i){ int u,v,w; scanf("%d%d%d",&u,&v,&w); e[u][v]=e[v][u]=w; } dijkstra(); printf("Scenario #%d: ",++cas); printf("%d ",dis[n]); } return 0; }
以上是关于poj1797(dijstra变形,求最小边的最大值)的主要内容,如果未能解决你的问题,请参考以下文章
POJ-2253 Frogger---最短路变形&&最大边的最小值
POJ-2263 Heavy Cargo---最短路变形&&最小边的最大值
poj1797 Heavy Transportation(最短路变形)