• 二分+最短路


    二分+最短路

    Time Limit:1000MS     Memory Limit:65536KB     64bit IO Format:%lld & %llu

    POJ 3662

    Description

    多年以后,笨笨长大了,成为了电话线布置师。由于地震使得某市的电话线全部损坏,笨笨是负责接到震中市的负责人。该市周围分布着N(1<=N<=1000)根据1……n顺序编号的废弃的电话线杆,任意两根线杆之间没有电话线连接,一共有p(1<=p<=10000)对电话杆可以拉电话线。其他的由于地震使得无法连接。

    第i对电线杆的两个端点分别是ai,bi,它们的距离为li(1<=li<=1000000)。数据中每对(ai,bi)只出现一次。编号为1的电话杆已经接入了全国的电话网络,整个市的电话线全都连到了编号N的电话线杆上。也就是说,笨笨的任务仅仅是找一条将1号和N号电线杆连起来的路径,其余的电话杆并不一定要连入电话网络。

    电信公司决定支援灾区免费为此市连接k对由笨笨指定的电话线杆,对于此外的那些电话线,需要为它们付费,总费用决定于其中最长的电话线的长度(每根电话线仅连接一对电话线杆)。如果需要连接的电话线杆不超过k对,那么支出为0.

    请你计算一下,将电话线引导震中市最少需要在电话线上花多少钱?

    Input

    输入文件的第一行包含三个数字n,p,k;

    第二行到第p+1行,每行分别都为三个整数ai,bi,li。

    Output

    一个整数,表示该项工程的最小支出,如果不可能完成则输出-1.

    Sample Input

    5 7 1
    1 2 5
    3 1 4
    2 4 8
    3 2 3
    5 2 9
    3 4 7
    4 5 6
    

    Sample Output

    4

    //挺有意思的一道题,要使第 k+1 大的边的值越小越好。想不到啊,spfa还能这么用,二分还能这么用。。。

    我觉得最神奇的一点是,最后的一次满足情况的 mid (即 ans )一定是第是这个图里面的边,并且这个值是第 k+1 大的边最小的情况。

    因为,小于这个值的话,这条边也会让 dis[n] 的值加 1 ,即不会满足 dis[n]<=k 的

    79ms

     1 #include <stdio.h>
     2 #include <string.h>
     3 
     4 #define MAXN 1005
     5 
     6 struct Edge{
     7     int v,w;
     8     int next;
     9 }edge[30005];
    10 int headlist[MAXN];
    11 
    12 int n,p,k,bian=0;
    13 
    14 void join(int a,int b,int c)
    15 {
    16     bian++;
    17     edge[bian].v=b;
    18     edge[bian].w=c;
    19     edge[bian].next=headlist[a];
    20     headlist[a]=bian;
    21 }
    22 
    23 int Q[1000];
    24 int vis[MAXN];
    25 int dis[MAXN];//大于limit的最少有多少个
    26 int spfa(int limit)
    27 {
    28     for (int i=1;i<=n;i++)
    29         dis[i]=10000000;//kanknkkkkkkkkkkkkk
    30     memset(vis,0,sizeof(vis));
    31 
    32     Q[0]=1;
    33     int l=0,r=1;
    34     dis[1]=0,vis[1]=1;
    35     while (l!=r)
    36     {
    37         int now=Q[l++];
    38         if (l==1000) l=0;
    39         vis[now]=0;
    40         int i=headlist[now];
    41         int mm=dis[now];
    42         while (i)
    43         {
    44             if (edge[i].w>limit) mm=dis[now]+1;
    45             else mm=dis[now];
    46             if (mm<dis[edge[i].v])
    47             {
    48                 dis[edge[i].v]=mm;
    49                 if (vis[edge[i].v]==0)
    50                 {
    51                     Q[r++]=edge[i].v;
    52                     if (r==1000) r=0;
    53                     vis[edge[i].v]=1;
    54                 }
    55             }
    56             i=edge[i].next;
    57         }
    58     }
    59     if (dis[n]<=k) return 1;//
    60     return 0;
    61 }
    62 
    63 int main()
    64 {
    65     scanf("%d%d%d",&n,&p,&k);
    66     int a,b,c;
    67     for (int i=1;i<=p;i++)
    68     {
    69         scanf("%d%d%d",&a,&b,&c);
    70         join(a,b,c);
    71         join(b,a,c);
    72     }
    73     int l=0,r=1000000,ans=-1;
    74     while (l<=r)
    75     {
    76         int mid=(l+r)/2;
    77         if (spfa(mid))
    78         {
    79             ans=mid;//记录后,看能不能有更小的值符合条件
    80             r=mid-1;
    81         }
    82         else l=mid+1;//不能的话,只能看有没更大的了
    83     }
    84     printf("%d
    ",ans);
    85     return 0;
    86 }
    View Code
  • 相关阅读:
    jquery全屏幻灯轮播焦点图
    PHP curl 上传文件版本兼容问题
    一个网站同一域名不同目录下的文件访问到的cookie值不同是什么原因?
    Linux系统查找清理磁盘大文件方法
    REDIS常用命令
    CentOS 6.4安装pip,CentOS安装python包管理安装工具pip的方法
    centos6 编译安装nodejs4.3
    centos yum安装php5.6.19 remi源按照
    Mac下用brew搭建PHP(LNMP/LAMP)开发环境
    为什么JAVA要提供 wait/notify 机制?是为了避免轮询带来的性能损失
  • 原文地址:https://www.cnblogs.com/haoabcd2010/p/6068598.html
Copyright © 2020-2023  润新知