• Divide and conquer:Telephone Lines(POJ 3662)


                    

                    电话线

      题目大意:一堆电话线要你接,现在有N个接口,总线已经在1端,要你想办法接到N端去,电话公司发好心免费送你几段不用拉网线,剩下的费用等于剩余最长电话线的长度,要你求出最小的费用。

      这一看又是一个最小化最大值的问题(也可以看成是最大化最小值的问题),常规方法一样的就是把这个费用二分就好,但是这道题是道图论题,不一定经过所有的点,那我们就以二分基准长度为界限,把小于基准长度的那一部分看成是0,大于等于基准长度的看成是1,这样我们只用SPFA算法算最短路径就可以了,非常的巧妙

      参考:http://poj.org/showmessage?message_id=181794

      PS:好久没写SPFA了,都忘记是怎么写了,重新定义长度的时候又忘记乘以2了WA一个晚上真是日了

      

      1 #include <iostream>
      2 #include <algorithm>
      3 #include <functional>
      4 #define SIZE 1010
      5 
      6 using namespace std;
      7 typedef int Position;
      8 
      9 struct _set
     10 {
     11     Position ed;
     12     int next;
     13     int length;
     14 }Path[20005];
     15 struct _head
     16 {
     17     int point;
     18 }Heads[SIZE];
     19 static int dist[SIZE];
     20 static bool visit[SIZE], oep[20005];
     21 static Position que[(SIZE + 1) * 2];
     22 
     23 void solve(const int, const int, const int, const int);
     24 bool SPFA(const int, const int, const int, const int);
     25 
     26 int main(void)
     27 {
     28     int Sum_Poles, Free_Cables, Sum_Path, length, L_Max;
     29     Position st, ed;
     30 
     31     while (~scanf("%d%d%d", &Sum_Poles, &Sum_Path, &Free_Cables))
     32     {
     33         L_Max = -1;
     34         for (int i = 0; i <= Sum_Poles; i++)
     35             Heads[i].point = -1;
     36         for (int i = 0; i < 2 * Sum_Path;)
     37         {
     38             scanf("%d%d%d", &st, &ed, &length);
     39             //无向图,两边都要存
     40             Path[i].ed = ed; Path[i].length = length; Path[i].next = Heads[st].point;
     41             Heads[st].point = i++;
     42 
     43             Path[i].ed = st; Path[i].length = length; Path[i].next = Heads[ed].point;
     44             Heads[ed].point = i++;
     45 
     46             L_Max = max(L_Max, length);
     47         }
     48         solve(Sum_Poles, Sum_Path, Free_Cables, L_Max);
     49     }
     50     return 0;
     51 }
     52 
     53 void solve(const int Sum_Poles, const int Sum_Path, const int Free_Cables, const int L_Max)
     54 {
     55     int lb = 0, rb = L_Max + 1, mid;
     56 
     57     while (rb - lb > 1)//对距离二分
     58     {
     59         mid = (lb + rb) >> 1;
     60         if (SPFA(mid, Sum_Path, Sum_Poles, Free_Cables)) lb = mid;
     61         else rb = mid;
     62         if (dist[Sum_Poles] == 0x3fffffff)
     63             //任何一次寻找过后,如果图能到N点,那么N的dist值一定不是0x3fffffff
     64             //否则,一定是不联通
     65         {
     66             printf("-1
    ");
     67             return;
     68         }
     69     }
     70     printf("%d
    ", lb);
     71 }
     72 
     73 bool SPFA(const int x, const int Sum_Path, const int Sum_Poles, const int Free_Cables)
     74 {
     75     int head = 0, back = 1, out, to;
     76 
     77     que[head] = 1;    //开始是从1开始的    
     78 
     79     for (int i = 0; i < 2 * Sum_Path; i++)
     80         oep[i] = Path[i].length < x ? 0 : 1;
     81 
     82     fill(dist, dist + Sum_Poles + 1, 0x3fffffff);
     83     memset(visit, 0, sizeof(visit));
     84     dist[1] = 0;
     85 
     86     while (head != back)
     87     {
     88         out = que[head]; head = (head + 1) % (2 * SIZE);
     89         visit[out] = 0;
     90 
     91         for (int k = Heads[out].point; k != -1; k = Path[k].next)
     92         {
     93             to = Path[k].ed;
     94             if (dist[out] + oep[k] < dist[to])
     95             {
     96                 dist[to] = dist[out] + oep[k];
     97                 if (!visit[to])
     98                 {
     99                     visit[to] = 1;
    100                     que[back] = to; back = (back + 1) % (2 * SIZE);
    101                 }
    102             }
    103         }
    104     }
    105     return dist[Sum_Poles] > Free_Cables;
    106 }

  • 相关阅读:
    关于闭包和作用域的问题
    中文字体@font-face的导入
    一个跑马灯插件(持续优化)
    关于JS的clone()函数编写的一些问题
    函数的自执行,变量提升和函数提升
    Android 之Map容器替换 SparseArray,ArrayMap,ArraySet
    Anndroid GC 那些事
    Spark Streaming实时计算
    REDIS基础要点
    zookeeper要点总结
  • 原文地址:https://www.cnblogs.com/Philip-Tell-Truth/p/5143826.html
Copyright © 2020-2023  润新知