zoukankan      html  css  js  c++  java
  • 洛谷P1396营救(Dijkstra/最小生成树/二分+BFS等)

    题目背景

    “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……

    题目描述

    妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了 ttt 区,而自己在 sss 区。

    该市有 mmm 条大道连接 nnn 个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从 sss 至 ttt 的路线,使得经过道路的拥挤度最大值最小。

    输入格式

    第一行有四个用空格隔开的 nnn,mmm,sss,ttt,其含义见【题目描述】。

    接下来 mmm 行,每行三个整数 u,v,wu, v, wu,v,w,表示有一条大道连接区 uuu 和区 vvv,且拥挤度为 www。

    两个区之间可能存在多条大道

    输出格式

    输出一行一个整数,代表最大的拥挤度。

    输入输出样例

    输入 #1
    3 3 1 3
    1 2 2
    2 3 1
    1 3 3
    输出 #1
    2
    这个题貌似有很多解法。
    Dij的话只需要改一下d数组的定义:d[i]为i到s的路径上的最大边的最小值。同时改一下松弛条件:只有当d[x]<=z<=d[y]或者z<=d[x]<=d[y]时才更新d[y]为max(d[x],z),因为max(d[x],z)此时是s到y的某条路径上的最大值,要拿这个去更新d[y]。
    题解区有大佬用的二分+BFS,很显然这是个最大值最小问题,所以二分是没有问题的。
    还有大佬跑最小生成树,“将边从小到大排序,然后克鲁斯卡尔最小生成树连边,这样当S和T第一次联通时,当前边的权值就是答案了.”注意到边是从小到大排序的,刚连上的时候肯定是当前最大边。很妙。
    #include <bits/stdc++.h>
    #define N 10005
    #define M 20005
    using namespace std;
    int n,m,s,t,tot=0,head[N],ver[2*M],edge[2*M],Next[2*M],d[N];//d[i]表示从s到i路径上的最大路径的最小值 
    bool v[N];
    priority_queue< pair<int,int> >q;
    void add(int x,int y,int z)
    {
        ver[++tot]=y,edge[tot]=z,Next[tot]=head[x],head[x]=tot;
    }
    void dijkstra()
    {
        d[s]=0;
        q.push(make_pair(-d[s],s));
        while(q.size())
        {
            int x=q.top().second;q.pop();
            if(v[x])continue;
            v[x]=1;
            int i;
            for(i=head[x];i;i=Next[i])
            {
                int y=ver[i],z=edge[i];
                if(d[y]>min(d[x],z))//小于等于的话就没必要更新了 
                {
                    if(z>d[x])
                    {
                        if(d[y]>z)//d[x] z d[y]
                        {
                            d[y]=z;
                            q.push(make_pair(-d[y],y));
                        }
                    }
                    else//z<=d[x]
                    {
                        if(d[y]>d[x])//z d[x] d[y]
                        {
                            d[y]=d[x];
                            q.push(make_pair(-d[y],y));
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        memset(d,0x3f3f3f3f,sizeof(d));
        memset(v,0,sizeof(v));
        int i;
        scanf("%d%d%d%d",&n,&m,&s,&t);
        for(i=1;i<=m;i++)
        {
            int x,y,z;
            scanf("%d%d%d",&x,&y,&z);
            add(x,y,z);
            add(y,x,z);
        }
        dijkstra();
        cout<<d[t];
        return 0;
    }
  • 相关阅读:
    nodejs windows下安装运行
    第一篇博客
    vc 动态链接库编程2
    vc 动态链接库编程
    原生js实现图片在线预览
    玩转 css3
    CSS Hack整理
    PHP stdClass Object转array
    aptana studio3 汉化方法
    玩转 css3 续
  • 原文地址:https://www.cnblogs.com/lipoicyclic/p/12718804.html
Copyright © 2011-2022 走看看