zoukankan      html  css  js  c++  java
  • 2013校队选拔——最短路——二分最大边的最小值

    1012: City Tour

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 63  Solved: 11
    [Submit][Status][Web Board]

    Description

    Alice想要从城市A出发到城市B,由于Alice最近比较穷(不像集训队陈兴老师是个rich second),所以只能选择做火车从A到B。不过Alice很讨厌坐火车,火车上人比较多,比较拥挤,所以Alice有很严格的要求:火车的相邻两站间的最大距离尽可能的短,这样Alice就可以在停站的时候下车休息一下。当然Alice希望整个旅途比较短。

    Input

    有多组测试数据。
    每组测试数据的第一行有两个整数N,M,A,B(N<=1000, M<=50000, N >=2, A,B<=N),其中N是城市的个数,M是城市间通火车的个数。
    A,B是Alice起始的城市与目的地城市,城市的标号从1开始。
    接下来的M行每行三个整数u,v,w表示从u到v和从v到u有一条铁路,距离为w, u,v<=N, w<=10000。

    Output

    对于每组测试数据输出满足Alice要求的从A到B的最短距离。

    Sample Input

    3 3 1 2
    1 2 80
    1 3 40
    2 3 50
    3 3 1 2
    1 2 90
    1 3 10
    2 3 20
    4 5 1 4
    1 2 8
    1 4 9
    1 3 10
    2 4 7
    3 4 8

    Sample Output

    90
    30
    15
     
     
    又是一年校队选拔,又坑在了二分这个题目上面。
    这个题目最短路部分不难
    关键是想到用二分
    之前思路很混乱,我一度也在想要记录每条路的最大边权值,然后对求出来的最短路,优先选择最大边权值最小的那条。。。但是这种思路首先没有落实到二分这个方法上来,其次,我是想边求最短路的时候,边比较此时的最大边权,然后取小的。。非常混乱
    记得上次显神就给我讲过最大值最小化问题,我竟然没有转化到这个最短路的题目来
    题目条件要使得两个站之间的距离越短越好。。。因此是在站与站的距离越的情况下,来进行最短路。
    因此,用二分枚举出最大边权值,(意思就是在该最大权值下,如果边权值大于它,则相当于不通),在枚举出的权值下,进行朴素的迪杰斯特拉最短路(安神用的SPFA,看起来很简洁。膜拜一下。)!
    最后坑爹的二分调试了我几个小时(比赛之后)。发现二分真的不是那么好写。。尤其是这道题目,枚举出来的量稍有差池,就输不出正确的值来。
    其实后来看了下浙西贫农的代码,忽然觉悟了,不是我的二分没写好,是在判断的时候,应该在边值可达的时候记录下此时的b点最短路值,否则总会发现输出inf
    还得练习一下分治专题。
     
    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #define ll long long
    #define inf 10000000
    using namespace std;
    int d[1005][1005];
    int city[1005];
    bool vis[1005];
    int n,m,a,b;
    int main()
    {
        while (scanf("%d %d %d %d",&n,&m,&a,&b)!=EOF)
        {
            int i,j,k;
            int mmax=0;
            int mmin=inf;
            for (i=0; i<=n; i++)
            {
                for (j=1; j<=n; j++)
                    d[i][j]=inf;
                city[i]=inf;
            }
    
            for (j=1; j<=m; j++)
            {
                int u,v,w;
                scanf("%d %d %d",&u,&v,&w);
                if (d[u][v]>w)
                    d[u][v]=d[v][u]=w;
                if (mmax<w) mmax=w;
                if (mmin>w) mmin=w;
            }
            city[a]=0;
            int ans=0;
            int l=mmin,r=mmax,mid;
            while (l<r) //二分部分。
            {
    
                memset(vis,0,sizeof vis);
                mid=(l+r)/2;
                for (int i2=1;i2<=n;i2++)//每次二分都要重置最短路
                {
                  city[i2]=inf;
                }
                city[a]=0;
                for (i=1;i<=n;i++)//进行朴素的Dijstla
                {
                    int min=inf,loc;
                    for (j=1;j<=n;j++)
                    {
                        if (vis[j]) continue;
                        if (min>city[j])
                        {
                            min=city[j];
                            loc=j;
                        }
                    }
                    vis[loc]=1;
                    for (k=1;k<=n;k++)
                    {
                       if (d[loc][k]>mid) continue;
                       if(vis[k]) continue;
                       if (city[k]>city[loc]+d[loc][k])
                        city[k]=city[loc]+d[loc][k];
    
                    }
                }
                if (city[b]>=inf) l=mid+1;
                else
    {
    ans=city[b];//应该在这里记录好结果。。。否则下一次二分如果是满足上面那个条件,则最终不是会输出inf r=mid;
    } } printf(
    "%d ",ans); } return 0; }
  • 相关阅读:
    天梯赛5-12 愿天下有情人都是失散多年的兄妹 【dfs】
    poj2718 Smallest Difference【贪心】
    HDU problem 5635 LCP Array【思维】
    codeforces 782C Andryusha and Colored Balloons【构造】
    HDU 4278 Faulty Odometer【进制转换】
    codeforces B. The Meeting Place Cannot Be Changed【二分】
    POJ 3264 Balanced Lineup 【线段树】
    HDU 1850
    CodeForces-714C
    HDU Problem 1247 Hat's Words 【字典树】
  • 原文地址:https://www.cnblogs.com/kkrisen/p/3275263.html
Copyright © 2011-2022 走看看