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

原文地址:https://www.cnblogs.com/FrankChen831X/p/11725615.html

时间: 2024-10-13 00:55:27

poj1797(dijstra变形,求最小边的最大值)的相关文章

ural 1076 KM求最小权匹配

贴模板~ KM算法引进了顶标函数,不断缩小这个顶标来让相等子图的可能范围扩大 #include<iostream> #include<cstring> //KM 复杂度O^3 using namespace std; const int N=200; int lx[N],ly[N];//顶标函数 int w[N][N];//图 bool vix[N],viy[N]; int linky[N];// int lack;//每次顶标函数扩大的增量 int n,m; bool find(

关于输入一组数据求最小的问题

问题链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1350 http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1408 两个问题,自己第一个代码是没有敲出来的,第二个代码虽然是搞定了, 但是在处理是分析不清楚,使用了两个for循环,导致时间上相对于别人的代码有很大的差距. 自己AC的1408: #include <iostream> #include <algorithm>

[经典面试题]给定一个有序(非降序)数组A,可含有重复元素,求最小的i使得A[i]等于target,不存在则返回-1

[题目] 给定一个有序(非降序)数组A,可含有重复元素,求最小的i使得A[i]等于target,不存在则返回-1. [分析] 此题也就是求target在数组中第一次出现的位置.这里可能会有人想先直接用原始的二分查找,如果不存在直接返回-1, 如果存在,然后再顺序找到这个等于target值区间的最左位置,这样的话,最坏情况下的复杂度就是O(n)了,没有完全发挥出二分查找的优势. 这里的解法具体过程请参考实现代码与注释. [代码] /*********************************

HDU 1565 (最大流+黑白染色化二分图求最小割)

http://acm.hdu.edu.cn/showproblem.php?pid=1565 思路:将横纵坐标和为偶尔染白色,其他染黑色,黑点连接源点,流量为该点的值,白点连接汇点,流量为该点的值,黑白点有相邻的就连边,值为无穷大.最后求最大流,即该图的最小割. PS:刚开始不明白为为什么最大流会等于最小割,为什么所有的点之和减去最小割就会等于答案. 我的理解是:整张图其实就跟连接管道一样,连接了黑点表示取了黑点那个值的流量,白点也是,而连接了相邻的黑白点求出的最大流就会是流量较小的那个的值.好

java实现求一个数组里最大值和最小值之前缺省的数的算法

问题描述: 求一个数组里最大值和最小值之间缺省的数,例如 int arrDemo = {1, 3, 7};  那么就要输出最小值1和最大值7之间缺少的数字2,4,5,6 代码如下,有更好的思路欢迎大家在评论区留言讨论 1 package test; 2 3 public class Test { 4 5 static int[] array = { 6 -10,0,3,3,9 7 }; 8 9 private static void printEmptyItems(int[] array) {

写一个方法求数组中的最大值,最小值,总和以及平均值。

class Program { /// <summary> /// 求数组中的最大值,最小值,总和以及平均值. /// </summary> /// <param name="nums">输入一个数组</param> /// <returns>返回一个新的数组(max,min,sum,avg)</returns> public static int[] GetMaxMinSumAvg(int[] nums) { i

HDU 3035 War(对偶图求最小割)

HDU 3035 War 题目链接 题意:根据图那样,给定一个网络,要求阻断s到t,需要炸边的最小代价 思路:显然的最小割,但是也显然的直接建图强行网络流会超时,这题要利用平面图求最小割的方法,把每一块当成一个点,共有边连边,然后每一个路径就是一个割,然后最短路就是最小割了 代码: #include <cstdio> #include <cstring> #include <vector> #include <queue> using namespace s

hdu 3746 Cyclic Nacklace (KMP求最小循环节)

//len-next[len]为最小循环节的长度 # include <stdio.h> # include <algorithm> # include <string.h> using namespace std; int len; char a[100010]; int next[100010]; void Getnext() { int i=0,j=-1; next[0]=-1; while(i<=len) { if(j==-1||a[i]==a[j]) i

LeetCode -- Triangle 路径求最小和( 动态规划问题)

人们常说"细节决定成败". 编码工作中,同样需要关注细节. 本文将给出3个小实例来说明编码中关注细节的重要性,同时给出作者对如何注意编码细节的一点见解(说的不对,请指正). 例1 这个问题如此地显而易见,竟然没有被发现. List<int> numList = new List<int>(); numList.Add(3); numList.Add(1); numList.Add(4); numList.Add(2); numList.Add(5); numLi