• P1396 营救


    P1396 营救
    218
    通过
    571
    提交
    题目提供者yeszy
    标签 二分 图论 并查集 福建省历届夏令营
    难度 普及-
    题目描述
    “咚咚咚……”“查水表!”原来是查水表来了,现在哪里找这么热心上门的查表员啊!小明感动的热泪盈眶,开起了门……
    妈妈下班回家,街坊邻居说小明被一群陌生人强行押上了警车!妈妈丰富的经验告诉她小明被带到了t区,而自己在s区
    该市有m条大道连接n个区,一条大道将两个区相连接,每个大道有一个拥挤度。小明的妈妈虽然很着急,但是不愿意拥挤的人潮冲乱了她优雅的步伐。所以请你帮她规划一条从s至t的路线,使得经过道路的拥挤度最大值最小。
    输入输出格式
    输入格式:
    第一行四个数字n,m,s,t。
    接下来m行,每行三个数字,分别表示两个区和拥挤度。
    (有可能两个区之间有多条大道相连。)
    输出格式:
    输出题目要求的拥挤度。
    输入输出样例
    输入样例#1:
    3 3 1 3
    1 2 2
    2 3 1
    1 3 3
    输出样例#1:
    2
    说明
    数据范围
    30% n<=10
    60% n<=100
    100% n<=10000,m<=2n,拥挤度<=10000
    题目保证1<=s,t<=n且s<>t,保证可以从s区出发到t区。
    样例解释:
    小明的妈妈要从1号点去3号点,最优路线为1->2->3。

    /*
    MST最小瓶颈生成树.
    定理:MST中的最长边必定小于其他生成树中的最长边. 
    */
    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #define MAXN 10001
    using namespace std;
    int n,m,father[MAXN],tot,ss,tt;
    struct data
    {
        int x,y,z;
    }s[MAXN*2];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    bool cmp(const data &x,const data &y)
    {
        return x.z<y.z;
    }
    int find(int x)
    {
        return x!=father[x]? father[x]=find(father[x]):x;
    }
    int main()
    {
        n=read();m=read();ss=read();tt=read();
        for(int i=1;i<=n;i++) father[i]=i;
        for(int i=1;i<=m;i++)
          s[i].x=read(),s[i].y=read(),s[i].z=read();    
        sort(s+1,s+m+1,cmp);
        for(int i=1;i<=m;i++)
        {
            int l1=find(s[i].x),l2=find(s[i].y);
            if(l1!=l2) tot++,father[l2]=l1;
            if(find(ss)==find(tt))
            {
                printf("%d",s[i].z);
                return 0;
            }
            if(tot==n-1) break;
        }
        return 0;
    }
    /*
    二分拥挤值.
    spfa大于拥挤值的边不选.
    然后判能不能到达终点.
    */
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define MAXN 10001
    using namespace std;
    int n,m,s,t,head[MAXN],tot,dis[MAXN];
    bool b[MAXN];
    struct data
    {
        int v,next,x;
    }e[MAXN*4];
    int read()
    {
        int x=0,f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
        return x*f;
    }
    void add(int u,int v,int x)
    {
        e[++tot].v=v;
        e[tot].x=x;
        e[tot].next=head[u];
        head[u]=tot;
    }
    bool spfa(int x)
    {
        int q[MAXN*2]={0},head1=1,tail=0;
        memset(b,0,sizeof(b));
        memset(dis,127/3,sizeof(dis));dis[s]=0;q[++tail]=s;b[s]=true;
        while(head1<=tail)
        {
            int u=q[head1++];b[u]=false;
            for(int i=head[u];i;i=e[i].next)
            {
                int v=e[i].v;
                if(!b[v]&&e[i].x<=x&&dis[v]>dis[u]+e[i].x)
                {
                    b[v]=true;
                    dis[v]=dis[u]+e[i].x;
                    q[++tail]=v;
                }
            }
        }
        if(dis[t]==dis[0]) return false;
        return true;
    }
    int erfen(int l,int r)
    {
        int mid,ans=0;
        while(l<=r)
        {
            mid=(l+r)>>1;
            if(spfa(mid)) ans=mid,r=mid-1;
            else l=mid+1;
        }
        return ans;
    }
    int main()
    {
        int x,y,z;
        n=read();m=read();s=read();t=read();
        for(int i=1;i<=m;i++)
        {
            x=read();y=read();z=read();
            add(x,y,z);add(y,x,z);
        }
        printf("%d",erfen(1,10000));
        return 0;
    }
  • 相关阅读:
    百度ECharts数据绑定诀窍
    SQL操作Json数据
    c# 如何得到一个字符的ASCII码
    Sql数据库收缩 语句特别快
    Hive中 使用 Round() 的坑
    [转]Hive 数据类型
    [转] Hive函数大全
    使用Hive Rest API 连接HDInsight
    Hive动态分区 参数配置及语法
    Js的引用赋值与传值赋值
  • 原文地址:https://www.cnblogs.com/nancheng58/p/6070779.html
Copyright © 2020-2023  润新知