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:\n",++cas); printf("%d\n\n",dis[n]); } return 0; }
朋友们,无论这个世界变得怎样,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。