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\n");
 67             return;
 68         }
 69     }
 70     printf("%d\n", 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 }

时间: 2024-10-05 16:42:40

Divide and conquer:Telephone Lines(POJ 3662)的相关文章

Divide and conquer:Aggressive Cows(POJ 2456)

侵略性的牛 题目大意:C头牛最大化他们的最短距离 常规题,二分法即可 1 #include <iostream> 2 #include <algorithm> 3 #include <functional> 4 5 using namespace std; 6 7 static int pos[100000]; 8 9 bool judge(const int, const int,const int); 10 void solve(const int, const i

Divide and conquer:Monthly Expense(POJ 3273)

Monthly Expense 题目大意:不废话,最小化最大值 还是直接套模板,不过这次要注意,是最小化最大值,而不是最大化最小值,判断的时候要注意 联动3258 1 #include <iostream> 2 #include <functional> 3 #include <algorithm> 4 5 using namespace std; 6 7 static int money_set[100010]; 8 9 void Search(const int,

Divide and Conquer:River Hopscotch(POJ 3258)

 去掉石头 题目大意:一群牛在河上的石头上跳来跳去,现在问你如何通过去掉M个石头,使得牛跳过石头的最短距离变得最大? 这一题比较经典,分治法的经典,二分法可以很方便处理这个问题,我们只要明白比较函数这个东西就可以了. 模板: while (……) { mid = (lb + rb) / 2; if (Judge_C(……)) else rb = mid; } while判断条件可以根据是整形还是浮点型灵活变换,Judge_C就是比较函数,几乎所有的分治算法都可以这样归纳,我们只要找到合适的比较函

POJ 3662 Telephone Lines【Dijkstra最短路+二分求解】

Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7214   Accepted: 2638 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of

poj 3662 Telephone Lines dijkstra+二分搜索

Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5696   Accepted: 2071 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of

POJ 3662 Telephone Lines (分层图)

Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6785   Accepted: 2498 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of

poj 3662 Telephone Lines spfa算法的灵活运用

题意: 给一个有n个结点的无向图,要求一条从1到n的路径,你可以让其中的k条免费,这条路径的花费是这条路径上剩下的边中长度的最大值,现在要求花费的最小值. 思路: 这道题可以首先想到二分枚举路径上的最大值,我觉得用spfa更简洁一些.spfa的本质是一种搜索算法,既然是搜索,就涉及到状态的转移.在一般求最短路的spfa算法中,当到结点u时,对e(u,v)只需做如下转移:if(d[v]>d[u]+w(e)) d[v]=d[u]+w(e).在跟一般的情况下,到结点u,对e(u,v)需做多种转移,比如

poj 3662 Telephone Lines(最短路+二分)

Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 6973   Accepted: 2554 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative, so he needs to pay for some of

poj3662 Telephone Lines【最短路】【二分】

http://poj.org/problem?id=3662 Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions:9310   Accepted: 3374 Description Farmer John wants to set up a telephone line at his farm. Unfortunately, the phone company is uncooperative,