公路修建问题

  OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多。然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕。所以,OIER Association组织成立了,旨在建立OI island的交通系统。 OI island有n个旅游景点,不妨将它们从1到n标号。现在,OIER Association需要修公路将这些景点连接起来。一条公路连接两个景点。公路有,不妨称它们为一级公路和二级公路。一级公路上的车速快,但是修路的花费要大一些。 OIER Association打算修n-1条公路将这些景点连接起来(使得任意两个景点之间都会有一条路径)。为了保证公路系统的效率, OIER Association希望在这n-1条公路之中,至少有k条(0≤k≤n-1)一级公路。OIER Association也不希望为一条公路花费的钱。所以,他们希望在满足上述条件的情况下,花费最多的一条公路的花费尽可能的少。 而你的任务就是,在给定一些可能修建的公路的情况下,选择n-1条公路,满足上面的条件。

输入描述 Input Description

  第一行有三个数n,k,m,这些数之间用空格分开。 N和k如前所述,m表示有m对景点之间可以修公路。以下的m行,每一行有4个正整数a,b,c1,c2表示在景点a与b 之间可以修公路,如果修一级公路,则需要c1的花费,如果修二级公路,则需要c2的花费。

输出描述 Output Description

  一个数据,表示花费最大的公路的花费。

样例输入 Sample Input
4 2 5
1 2 6 5
1 3 3 1
2 3 9 4
2 4 6 1
3 4 4 2
样例输出 Sample Output

4


  或许这是第一道自己想并且打AC的HNOI题目。。。。(虽然最后还是看了一会题解)

  显然我们可以直接二分答案,这一步的复杂度为O(log c)二分的判断就是利用克鲁斯卡尔算法,首先跑最多可以使用多少条a级公路,再跑可以使用多少条b级公路。

  注意的地方在于只要保证了a级公路选择的尽可能多就可以保证正确性!

AC代码:

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<cstring>
#define ll long long
#define maxn 100010
ll i,j,k,x,n,m,y,le,ri,h1,h2,father[maxn],bj[maxn];
ll min(ll x,ll y) {if (x<y) return x;else return y;}
struct node{
ll l,r,a,b,llg;
}w[maxn*2];
using namespace std;
ll find(ll x) //递归实现 路径压缩
{
if (father[x]!=x) father[x]=find(father[x]);
return father[x];
}
void unionn(ll r1,ll r2) //集合合并
{
father[r2]=r1;
}
bool cmp(const node & x,const node & y)
{
//if (x.llg==1) h1=x.a; else h1=x.b;
//if (y.llg==1) h2=y.a; else h2=y.b;
return x.b<y.b;
}
bool pd(ll mid)
{
for (i=1;i<=m;i++) {/*if (w[i].a<=mid) w[i].llg=1;else w[i].llg=0;*/ bj[i]=0;}
for (i=1;i<=n;i++) father[i]=i;
ll js=0,tot=0;
for (i=1;i<=m;i++)
{
if (w[i].a>mid) continue;
if (find(w[i].l)!=find(w[i].r) )
{
js++;
unionn(find(w[i].l),find(w[i].r));
tot++;
bj[i]=1;
}
if (js==n-1) break;
}
for (i=1;i<=m;i++)
{
if (js==n-1) break;
if (w[i].b>mid || bj[i]) continue;
if (find(w[i].l)!=find(w[i].r) )
{
js++;
unionn(find(w[i].l),find(w[i].r));
bj[i]=1;
}
}
if (js==n-1 && tot>=k) return true;else return false;
}
int main()
{
cin>>n>>k>>m;
for (i=1;i<=m;i++) scanf("%d%d%d%d",&w[i].l,&w[i].r,&w[i].a,&w[i].b);
le=1; ri=30000;
sort(w+1,w+m+1,cmp);
while (le!=ri)
{
if (pd((le+ri)/2)) ri=(le+ri)/2; else le=(le+ri)/2+1;
}
cout<<le;
return 0;
}

HNOI2006-公路修建问题(二分答案+并查集)的更多相关文章

  1. [HNOI2006]公路修建问题 (二分答案,并查集)

    题目链接 Solution 二分答案+并查集. 由于考虑到是要求花费的最小值,直接考虑到二分. 然后对于每一个二分出来的答案,模拟 \(Kruskal\) 的过程再做一遍连边. 同时用并查集维护联通块 ...

  2. [BZOJ1196][HNOI2006]公路修建问题 二分答案+最小生成树

    Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那 里的交通情况还是很糟糕.所以,OIER Association组 ...

  3. 洛谷P2323 [HNOI2006] 公路修建问题 [二分答案,生成树]

    题目传送门 公路修建问题 题目描述 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Associa ...

  4. BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1196 [题目大意] 对于每条可能维修的公路可选择修一级公路或者二级公路,价值不同 要求 ...

  5. bzoj 1196: [HNOI2006]公路修建问题 二分+并查集

    题目链接 1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1576  Solved: 909[Submit ...

  6. bzoj 1196: [HNOI2006]公路修建问题(二分+贪心)

    传送门 解题思路 看到最大,肯定要先想二分答案.二分之后首先从小到大枚举\(k\)个小于\(lim\)的所有一级公路,然后用并查集连到一起,然后就在剩下的里面从小到大找n-1-k个二级公路,模仿最小生 ...

  7. 洛谷P1991无线通讯网[kruskal | 二分答案 并查集]

    题目描述 国防部计划用无线网络连接若干个边防哨所.2 种不同的通讯技术用来搭建无线网络: 每个边防哨所都要配备无线电收发器:有一些哨所还可以增配卫星电话. 任意两个配备了一条卫星电话线路的哨所(两边都 ...

  8. BZOJ 1196 二分答案+并查集

    http://www.lydsy.com/JudgeOnline/problem.php?id=1196 题目大意:n个城市,m-1条路,每条路有一级公路和二级公路之分,你要造n-1条路,一级公路至少 ...

  9. HDU-3081-Marriage Match 2(最大流, 二分答案, 并查集)

    链接: https://vjudge.net/problem/HDU-3081 题意: Presumably, you all have known the question of stable ma ...

随机推荐

  1. linux网站目录及Apache权限的设置

    apache服务器访问权限设置禁止所有访问:Options Indexes FollowSymLinks 改为 Option None   Apache单个或多个目录禁止访问方法   这种方法通常用来 ...

  2. ASP.NET MVC下的四种验证编程方式【转】

    ASP.NET MVC采用Model绑定为目标Action生成了相应的参数列表,但是在真正执行目标Action方法之前,还需要对绑定的参数实施验证以确保其有效 性,我们将针对参数的验证成为Model绑 ...

  3. 《深度探索C++对象模型》3

    第六章:执行期语意学 全局对象的初始化: 局部静态对象的初始化: 构建对象数组的vec_new()函数: 针对数组的new操作: placement operator new: 反聚合提高效率: 模板 ...

  4. 《深度探索C++对象模型》2

    第四章: function语意学 非静态成员函数: 名称的特殊处理: 静态成员函数由于缺乏this指针,因此差不多等于非成员函数: virtual table布局(单一继承): 单一继承下函数调用: ...

  5. for_each()的返回值

    有三种办法可以从“运用了function object”的算法中获取“结果”或“反馈”: 1.在外部持有状态,并让function object指向它: 2.以by reference方式传递func ...

  6. mysql转换引擎的方法

    有很多方法可以将表的存储引擎转换成另外一种引擎,每种方法都各有优缺点: A:alter table 将表从一个引擎直接改为另外一个引擎最简单的办法 alter table tb_name engine ...

  7. 浅谈mysql mvcc

    以下为个人理解,如有错误,还望指正!! mysql的大多数事务型存储引擎实现的都不是简单的行级锁,基于提升并发性能的考虑,他们一般都同时实现了多版本并发控制,可以认为MVCC是行级锁的一个变种,但是它 ...

  8. python day5--正则表达式

    #----正则表达式 import re elink = '<a href="(.*)">(.*)</a>' info = '<a href=&quo ...

  9. 【转】MYSQL入门学习之三:全文本搜索

    转载地址:http://www.2cto.com/database/201212/173873.html 一.理解全文本搜索   www.2cto.com   1.MyISAM支持全文本搜索,而Inn ...

  10. MNIST手写数字数据库

    手写数字库很容易建立,但是总会很浪费时间.Google实验室的Corinna Cortes和纽约大学柯朗研究所的Yann LeCun建有一个手写数字数据库,训练库有60,000张手写数字图像,测试库有 ...