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, so he needs to pay for some of the cables required to connect his farm to the phone system.

There are N (1 ≤ N ≤ 1,000) forlorn telephone poles conveniently numbered 1..N that are scattered around Farmer John‘s property; no cables connect any them. A total of P (1 ≤ P ≤ 10,000) pairs of poles can be connected by a cable; the rest are too far apart.

The i-th cable can connect the two distinct poles Ai and Bi, with length Li (1 ≤ Li ≤ 1,000,000) units if used. The input data set never names any {AiBi} pair more than once. Pole 1 is already connected to the phone system, and pole N is at the farm. Poles 1 and need to be connected by a path of cables; the rest of the poles might be used or might not be used.

As it turns out, the phone company is willing to provide Farmer John with K (0 ≤ K < N) lengths of cable for free. Beyond that he will have to pay a price equal to the length of the longest remaining cable he requires (each pair of poles is connected with a separate cable), or 0 if he does not need any additional cables.

Determine the minimum amount that Farmer John must pay.

Input

* Line 1: Three space-separated integers: NP, and K
* Lines 2..P+1: Line i+1 contains the three space-separated integers: AiBi, and Li

Output

* Line 1: A single integer, the minimum amount Farmer John can pay. If it is impossible to connect the farm to the phone company, print -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

Source

USACO 2008 January Silver

题意:

【感觉题意描述很不清啊,一会长度一会段的】

有$n$个点,$p$条边,每条边有一个权值(花费)。将第$1$个点和第$n$个点连通,并且可以有$k$条边是免费的。剩下的不免费的边的最大值作为最终的花费。求最终花费的最小值。

思路:

刚开始题意理解错了。以为是有$k$长度的是免费的,边的那个权值是长度。想了半天搞不懂。

后来发现其实就是求一个使路径上第$k+1$大的边权尽量小的路径。【虽然还是不会】

因为当我们支付的钱变多时,合法的路径一定包含了花费更少的路径。答案具有单调性。

所以我们可以二分答案。【注意想题目答案的单调性尝试二分】

这时候问题就变成了,把价格超过$mid$的边花费看成是$1$,不超过的边花费看成是$0$,然后求$1~N$的最短路是否不超过$k$就可以了。

要注意考虑$1$和$N$不连通的情况,输出是$-1$

虐狗宝典上还有一个思路是用dp,但是我不是很会写。

用$D[x,p]$表示从$1$号节点到基站$x$,途中已经指定了$p$条电缆免费时,经过的路径上最贵的电缆的花费最小是多少(选择一条$1$到$x$的路径,使路径上第$p+1$大的边权尽量小)。若有一条从$x$到$y$长度是$z$的无向边,用$max(D[x,p],z)$更新$D[y,p]$的最小值,用$D[x,p]$更新$D[y, p+1]$的最小值。前者表示不在电缆$(x,y,z)$上使用免费升级服务,后者表示使用。用迭代的思想,借助SPFA进行动态规划,直至所有状态收敛。

还可以把图中节点拓展到二维,用二元组$(x,p)$表示一个节点,从$(x,p)$到$(y,p)$有长度为$z$的边,从$(x,p)$到$(y,p+1)$有长度为0的边。问题就变成了$N*K$个点,$P*K$条边的广义单源最短路问题。

  1 #include<iostream>
  2 //#include<bits/stdc++.h>
  3 #include<cstdio>
  4 #include<cmath>
  5 #include<cstdlib>
  6 #include<cstring>
  7 #include<algorithm>
  8 #include<queue>
  9 #include<vector>
 10 #include<set>
 11 #include<climits>
 12 using namespace std;
 13 typedef long long LL;
 14 #define N 100010
 15 #define pi 3.1415926535
 16
 17 const int maxn = 1005;
 18 const int maxp = 10005;
 19
 20 int n, p, k;
 21 struct node{
 22     int v, w, nxt;
 23 }e[maxp * 2];
 24 int tot = 0, head[maxn];
 25 LL dis[maxn];
 26 bool vis[maxn];
 27
 28 void addedge(int u, int v, int w)
 29 {
 30     e[tot].v = v;
 31     e[tot].w = w;
 32     e[tot].nxt = head[u];
 33     head[u] = tot++;
 34     e[tot].v = u;
 35     e[tot].w = w;
 36     e[tot].nxt = head[v];
 37     head[v] = tot++;
 38 }
 39
 40 int dijkstra(int mid)
 41 {
 42     memset(dis, 0x3f, sizeof(dis));
 43     memset(vis, 0, sizeof(vis));
 44     dis[1] = 0;
 45     priority_queue<pair<LL, int> >que;
 46     que.push(make_pair(0, 1));
 47     while(que.size()){
 48         int x = que.top().second;que.pop();
 49         if(vis[x])continue;
 50         vis[x] = true;
 51         for(int i = head[x]; i != -1; i = e[i].nxt){
 52             int y = e[i].v, z = e[i].w;
 53             if(z > mid)z = 1;
 54             else z = 0;
 55             if(dis[y] > dis[x] + z){
 56                 dis[y] = dis[x] + z;
 57                 que.push(make_pair(-dis[y], y));
 58             }
 59         }
 60     }
 61     return dis[n];
 62 }
 63
 64 int main()
 65 {
 66     while(scanf("%d%d%d", &n, &p, &k) != EOF){
 67         for(int i = 0; i < n; i++){
 68             head[i] = -1;
 69         }
 70         tot = 0;
 71
 72         int ed = -1;
 73         for(int i = 0; i < p; i++){
 74             int u, v, w;
 75             scanf("%d%d%d", &u, &v, &w);
 76             ed = max(ed, w);
 77             addedge(u, v, w);
 78         }
 79
 80         //printf("%d\n", dijkstra(0));
 81         if(dijkstra(0) == 1061109567)printf("-1\n");
 82         else{
 83             int st = 0, ans;
 84             while(st <= ed){
 85                 int mid = (st + ed) / 2;
 86                 if(dijkstra(mid) <= k){
 87                     ans = mid;
 88                     ed = mid - 1;
 89                 }
 90                 else{
 91                     st = mid + 1;
 92                 }
 93             }
 94             printf("%d\n", ans);
 95         }
 96
 97
 98     }
 99     return 0;
100 }

原文地址:https://www.cnblogs.com/wyboooo/p/9966149.html

时间: 2024-10-13 12:46:05

poj3662 Telephone Lines【最短路】【二分】的相关文章

POJ3662 Telephone Lines (dijkstra+二分)

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 the cables required to connect his farm to the phone system. There are N (1 ≤ N ≤ 1,000) forlorn telephone pol

POJ3662 Telephone Lines( dijkstral + 二分 )

POJ3662 Telephone Lines 题目大意:要在顶点1到顶点n之间建一条路径,假设这条路径有m条边,其中有k条边是免费的,剩余m-k条边是要收费的, 求这m-k条边中花费最大的一条边的最小花费. 让m条边中原本花费最大的k条边成为免费的边,则这时m-k条边中花费最大的一条边的花费最小. 二分枚举m-k条边中花费最大的一条边的最小花费x,dijkstra求最短路径时,将花费大于x的边的花费设为1(花费为INF的边不变),花费小于等于x的边设为 0,则d[v-1]中返回的就是花费大于x

[Usaco2007 Jan]Telephone Lines架设电话线[二分答案+最短路思想]

Description Farmer John打算将电话线引到自己的农场,但电信公司并不打算为他提供免费服务.于是,FJ必须为此向电信公司支付一定的费用. FJ的农场周围分布着N(1 <= N <= 1,000)根按1..N顺次编号的废弃的电话线杆,任意两根电话线杆间都没有电话线相连.一共P(1 <= P <= 10,000)对电话线杆间可以拉电话线,其余的那些由于隔得太远而无法被连接. 第i对电话线杆的两个端点分别为A_i.B_i,它们间的距离为 L_i (1 <= L_i

[POJ3662] Telephone Lines

题意:n个点,m条边,有k次机会免费走过一条边,最小化1-n的最大边权 题解:spfa+二分 这题好像克我......,一开始写了个二分+spfa在洛谷上A了,poj上莫名wa掉 然后写另一种方法,读入读成点数了,一直没发现,wa了一万年...... 二分最大边权 check把大于mid的边赋为1,小于等于mid的赋为0,spfa即可 #include<iostream> #include<cstdio> #include<cstdlib> #include<cs

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

[bzoj1614][Usaco2007Jan]Telephone Lines 架设电话线_二分答案_最短路

Telephone Lines bzoj-1614 Usaco-2007Jan 题目大意:给你一个n个点m条边的带边权无向图,求最短路.可以选取k条边免费. 注释:$1\le n\le 10^3$,$1\le m\le 10^5$ 想法:一眼分层图最短路啊! 我都想出来了就上网查一下题解吧 卧槽??二分+spfa?? 其实这个题不用分层图 我们二分答案,二分出最大值,然后将图中所有比mid大的边设为1,小的设为0,然后跑最短路.如果最短路的值比k大,说明最大值一定比二分的mid大.因为我的最短路

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

bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线*

bzoj1614[Usaco2007 Jan]Telephone Lines架设电话线 题意: n个节点,1号节点已经连入互联网,现在需要将整个图连入网络.有K条边可以免费连接,最后总费用为所有连边费用的最大值,求最小总费用.n≤10000 题解: 二分费用,将连边费用大于二分值的长度记为1,否则记为0,求最短路,如果到某个点的距离超过k,则需要增加答案,继续二分. 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include &l

hust 1039 Telephone Lines

题目描述 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 the cables required to connect his farm to the phone system. There are N (1 <= N <= 1,000) forlorn telep