↓ 跳过正文
  1. Posts/

BZOJ 1614: [Usaco2007 Jan]Telephone Lines架设电话线 (二分+spfa)

·1493 字·3 分钟

1614: [Usaco2007 Jan]Telephone Lines架设电话线
#

Time Limit: 5 Sec Memory Limit: 64 MB Submit: 1325 Solved: 570 [Submit][Status][Discuss]

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 <= 1,000,000)。数据中保证每对{A_i,B_i}最多只出现1次。编号为1的电话线杆已经接入了全国的电话网络,整个农场的电话线全都连到了编号为N的电话线杆上。也就是说,FJ的任务仅仅是找一条将1号和N号电话线杆连起来的路径,其余的电话线杆并不一定要连入电话网络。 经过谈判,电信公司最终同意免费为FJ连结K(0 <= K < N)对由FJ指定的电话线杆。对于此外的那些电话线,FJ需要为它们付的费用,等于其中最长的电话线的长度(每根电话线仅连结一对电话线杆)。如果需要连结的电话线杆不超过 K对,那么FJ的总支出为0。 请你计算一下,FJ最少需要在电话线上花多少钱。

Input
#

  • 第1行: 3个用空格隔开的整数:N,P,以及K

  • 第2..P+1行: 第i+1行为3个用空格隔开的整数:A_i,B_i,L_i

Output
#

  • 第1行: 输出1个整数,为FJ在这项工程上的最小支出。如果任务不可能完成, 输出-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

输入说明:

一共有5根废弃的电话线杆。电话线杆1不能直接与电话线杆4、5相连。电话 线杆5不能直接与电话线杆1、3相连。其余所有电话线杆间均可拉电话线。电信 公司可以免费为FJ连结一对电话线杆。

Sample Output
#

4

输出说明:

FJ选择如下的连结方案:1->3;3->2;2->5,这3对电话线杆间需要的 电话线的长度分别为4、3、9。FJ让电信公司提供那条长度为9的电话线,于是, 他所需要购买的电话线的最大长度为4。

HINT
#

思路:一开始把电话线条数和长度分别作为第一第二关键字,然后 spfa。然后记录路径,找 k 个最大的之后,剩下的中最长的电话线就是答案。发现样例就是反例……智力 -2。

正确的做法是二分电话线的最大长度,大于最大长度的电话线交给电信公司去搞,看交给电信公司搞的电话线数目是否小于等于 k。

二分的功夫还是不到家呀,想不到。 不过这道题和那个中国印度被喜马拉雅山脉阻隔,二分+bfs判断连通性的题目有点类似呢。

代码实现
  1/* ***********************************************
  2Author :111qqz
  3Created Time :2016年04月02日 星期六 17时50分13秒
  4File Name :code/bzoj/1614.cpp
  5************************************************ */
  6
  7#include <cstdio>
  8#include <cstring>
  9#include <iostream>
 10#include <algorithm>
 11#include <vector>
 12#include <queue>
 13#include <set>
 14#include <map>
 15#include <string>
 16#include <cmath>
 17#include <cstdlib>
 18#include <ctime>
 19#define fst first
 20#define sec second
 21#define lson l,m,rt<<1
 22#define rson m+1,r,rt<<1|1
 23#define ms(a,x) memset(a,x,sizeof(a))
 24typedef long long LL;
 25#define pi pair < int ,int >
 26#define MP make_pair
 27
 28using namespace std;
 29const double eps = 1E-8;
 30const int dx4[4]={1,0,0,-1};
 31const int dy4[4]={0,-1,1,0};
 32const int inf = 0x3f3f3f3f;
 33const int N=1E3+7;
 34int n,m,k;
 35int d[N];
 36bool inq[N];
 37vector < pi >edge[N];
 38
 39void init()
 40{
 41    for ( int i = 0 ; i <= n ; i++) edge[i].clear();
 42
 43}
 44
 45int spfa(int X) //X表示最大花费
 46{
 47    queue<int>q;
 48    ms(inq,false);
 49    ms(d,0x3f);
 50    q.push(1);
 51    inq[1] = true;
 52    d[1] = 0; // d[i]表示从1到i需要电信公司帮忙建的电话线杆的个数。
 53
 54
 55    while (!q.empty())
 56    {
 57	int u = q.front();
 58	q.pop();
 59	inq[u] = false;
 60
 61	int siz = edge[u].size();
 62
 63	for ( int i = 0 ; i < siz ; i++)
 64	{
 65	    int v = edge[u][i].fst;
 66	    int w = edge[u][i].sec>X?1:0;
 67
 68	    if (d[v]>d[u]+w)
 69	    {
 70		d[v] = d[u] + w;
 71		if (inq[v]) continue;
 72		inq[v] = true;
 73		q.push(v);
 74	    }
 75	}
 76    }
 77    return d[n];
 78
 79}
 80
 81void bin()
 82{
 83    int l = 0 ;
 84    int r = 1000000;
 85    int mid;
 86    int ans;
 87
 88    while (l<=r)
 89    {
 90	mid = (l+r)/2;
 91	if (spfa(mid)<=k) ans = mid,r=mid-1;
 92	else l = mid + 1;
 93    }
 94    printf("%d\n",ans);
 95}
 96int main()
 97{
 98	#ifndef  ONLINE_JUDGE
 99	freopen("code/in.txt","r",stdin);
100  #endif
101
102	init();
103	scanf("%d%d%d",&n,&m,&k);
104	for ( int i = 1 ; i <= m ; i++)
105	{
106	    int u,v,w;
107	    scanf("%d%d%d",&u,&v,&w);
108	    edge[u].push_back(MP(v,w));//以电话线数目为第一关键字,长度为第二关键字。
109	    edge[v].push_back(MP(u,w));
110	}
111	if (spfa(inf)==inf)
112	{
113	    puts("-1");
114	    return 0;
115	}
116	bin();
117
118  #ifndef ONLINE_JUDGE
119  fclose(stdin);
120  #endif
121    return 0;
122}

相关文章

BZOJ 1631: [Usaco2007 Feb]Cow Party (SPFA)

·906 字·2 分钟
1631: [Usaco2007 Feb]Cow Party # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 670 Solved: 493 [Submit][Status][Discuss] Description # 农场有N(1≤N≤1000)个牛棚,每个牛棚都有1只奶牛要参加在X牛棚举行的奶牛派对.共有M(1≤M≤100000)条单向路连接着牛棚,第i条路需要Ti的时间来通过.牛们都很懒,所以不管是前去X牛棚参加派对还是返回住所,她们都采用了用时最少的路线.那么,用时最多的奶牛需要多少时间来回呢? Input # 第1行:三个用空格隔开的整数.

hdu 3790 最短路径问题 (spfa模板题)

·472 字·1 分钟
hdu 3790 题目链接 题意:给出n个点m条无向边,每条边有一个距离和一个花费。给出s,t。问从s到t的最短距离以及最短距离时的最小花费。当有多个距离最短的方案时,选取花费最少的。

BZOJ 1650: [Usaco2006 Dec]River Hopscotch 跳石子 (二分)

·1042 字·3 分钟
1650: [Usaco2006 Dec]River Hopscotch 跳石子 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 440 Solved: 290 [Submit][Status][Discuss] Description # Every year the cows hold an event featuring a peculiar version of hopscotch that involves carefully jumping from rock to rock in a river. The excitement takes place on a long, straight river with a rock at the start and another rock at the end, L units away from the start (1 <= L <= 1,000,000,000). Along the river between the starting and ending rocks, N (0 <= N <= 50,000) more rocks appear, each at an integral distance Di from the start (0 < Di < L). To play the game, each cow in turn starts at the starting rock and tries to reach the finish at the ending rock, jumping only from rock to rock. Of course, less agile cows never make it to the final rock, ending up instead in the river. Farmer John is proud of his cows and watches this event each year. But as time goes by, he tires of watching the timid cows of the other farmers limp across the short distances between rocks placed too closely together. He plans to remove several rocks in order to increase the shortest distance a cow will have to jump to reach the end. He knows he cannot remove the starting and ending rocks, but he calculates that he has enough resources to remove up to M rocks (0 <= M <= N). FJ wants to know exactly how much he can increase the shortest distance before he starts removing the rocks. Help Farmer John determine the greatest possible shortest distance a cow has to jump after removing the optimal set of M rocks.

BZOJ 1639: [Usaco2007 Mar]Monthly Expense 月度开支 (二分)

·1018 字·3 分钟
1639: [Usaco2007 Mar]Monthly Expense 月度开支 # Time Limit: 5 Sec Memory Limit: 64 MB Submit: 767 Solved: 381 [Submit][Status][Discuss] Description # Farmer John是一个令人惊讶的会计学天才,他已经明白了他可能会花光他的钱,这些钱本来是要维持农场每个月的正常运转的。他已经计算了他以后N(1<=N<=100,000)个工作日中每一天的花费moneyi(1<=moneyi<=10,000),他想要为他连续的M(1<=M<=N)个被叫做“清算月”的结帐时期做一个预算,每一个“清算月”包含一个工作日或更多连续的工作日,每一个工作日都仅被包含在一个“清算月”当中。 FJ的目标是安排这些“清算月”,使得每个清算月的花费中最大的那个花费达到最小,从而来决定他的月度支出限制。