BZOJ 1196 [HNOI2006]公路修建问题:二分 + 贪心生成树check(类似kruskal)
题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1196
题意:
n个城市,m对城市之间可以修公路。
公路有两种,一级公路和二级公路,在第i对城市之间修的花费分别为c1[i],c2[i]。
你需要修n-1条公路,连接起所有城市(一棵树),并且至少有k条一级公路。
问你“花费最大的一条公路”的最小花费(最大值最小)。
题解:
O(log(c))二分 * O(m)生成树check + O(mlog(m))预先将边排序
二分:
二分答案(可能的最大一条公路的花费)。
check:
现在二分的值为now,要求所有边的花费 <= now.
所以贪心下:
对于每条边,只要不超过now,并且属于不同集合:能修一级就修一级,不行再修二级,然后加入生成树中。
并且还要先考虑最有可能可以修一级公路的边,所以预先将所有边按c1从小到大排序。
整个过程类似kruskal。。。
最后如果是一棵树(cnt==n-1),并且一级公路数量足够(super>=k),则答案可行。
AC Code:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <vector>
#define MAX_N 10005
#define COST_MAX 30005 using namespace std; struct Edge
{
int sour;
int dest;
int fst;
int sec;
Edge(int _sour,int _dest,int _fst,int _sec)
{
sour=_sour;
dest=_dest;
fst=_fst;
sec=_sec;
}
Edge(){}
friend bool operator < (const Edge &a,const Edge &b)
{
return a.fst<b.fst;
}
}; int n,m,k;
int ans;
int par[MAX_N];
vector<Edge> edge; void read()
{
cin>>n>>k>>m;
m--;
int a,b,c1,c2;
for(int i=;i<m;i++)
{
cin>>a>>b>>c1>>c2;
edge.push_back(Edge(a,b,c1,c2));
}
} void init_union_find()
{
for(int i=;i<=n;i++)
{
par[i]=i;
}
} int find(int x)
{
return par[x]==x?x:par[x]=find(par[x]);
} void unite(int x,int y)
{
int px=find(x);
int py=find(y);
if(px==py) return;
par[px]=py;
} bool same(int x,int y)
{
return find(x)==find(y);
} bool check(int now)
{
init_union_find();
int cnt=;
int super=;
for(int i=;i<m;i++)
{
Edge temp=edge[i];
if(min(temp.fst,temp.sec)<=now)
{
if(!same(temp.sour,temp.dest))
{
cnt++;
if(temp.fst<=now) super++;
unite(temp.sour,temp.dest);
}
}
}
return cnt==n- && super>=k;
} void solve()
{
sort(edge.begin(),edge.end());
int lef=;
int rig=COST_MAX;
while(rig-lef>)
{
int mid=(lef+rig)/;
if(check(mid)) rig=mid;
else lef=mid;
}
ans=rig;
} void print()
{
cout<<ans<<endl;
} int main()
{
read();
solve();
print();
}
BZOJ 1196 [HNOI2006]公路修建问题:二分 + 贪心生成树check(类似kruskal)的更多相关文章
- bzoj 1196: [HNOI2006]公路修建问题(二分+贪心)
传送门 解题思路 看到最大,肯定要先想二分答案.二分之后首先从小到大枚举\(k\)个小于\(lim\)的所有一级公路,然后用并查集连到一起,然后就在剩下的里面从小到大找n-1-k个二级公路,模仿最小生 ...
- bzoj 1196: [HNOI2006]公路修建问题 二分+并查集
题目链接 1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1576 Solved: 909[Submit ...
- BZOJ 1196: [HNOI2006]公路修建问题 Kruskal/二分
1196: [HNOI2006]公路修建问题 Time Limit: 1 Sec Memory Limit: 162 MB 题目连接 http://www.lydsy.com/JudgeOnline ...
- 【最小生成树】BZOJ 1196: [HNOI2006]公路修建问题
1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1435 Solved: 810[Submit][Sta ...
- BZOJ 1196: [HNOI2006]公路修建问题( MST )
水题... 容易发现花费最大最小即是求 MST 将每条边拆成一级 , 二级两条 , 然后跑 MST . 跑 MST 时 , 要先加 k 条一级road , 保证满足题意 , 然后再跑普通的 MST . ...
- BZOJ 1196 [HNOI2006]公路修建问题(二分答案+并查集)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1196 [题目大意] 对于每条可能维修的公路可选择修一级公路或者二级公路,价值不同 要求 ...
- bzoj 1196: [HNOI2006]公路修建问题
Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织 ...
- 洛谷P2323 [HNOI2006] 公路修建问题 [二分答案,生成树]
题目传送门 公路修建问题 题目描述 OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Associa ...
- [HNOI2006]公路修建问题 (二分答案,并查集)
题目链接 Solution 二分答案+并查集. 由于考虑到是要求花费的最小值,直接考虑到二分. 然后对于每一个二分出来的答案,模拟 \(Kruskal\) 的过程再做一遍连边. 同时用并查集维护联通块 ...
随机推荐
- Zabbix的前台SQL注射漏洞利用
今年8月份Map在wooyun上发了个Zabbix某前台SQL注射漏洞 ,11月份才公开. 漏洞详情大约是这样的: 在zabbix前端存在一个SQL注射漏洞,由于zabbix前台可以在zabbix的s ...
- centos下lvs配置
一.lvs-nat模式 网络配置: lvs-server eth0 :host-only adapter 192.168.56.101 lvs-server eth1 :Internal 192.16 ...
- VueJS自定义全局和局部指令
除了默认设置的核心指令( v-model 和 v-show ), Vue 也允许注册自定义指令. 使用directive自定义全局指令 下面我们注册一个全局指令 v-focus, 该指令的功能是在页面 ...
- CPU_CState_PState and then ACPI on Wiki
http://wenku.baidu.com/link?url=eHbdT4EjdJx3dsQETGUIL8q1K3_EyuzGLWT0G103AEca0vs0gHR_v_3c0oaUL2gbkrr8 ...
- NativeBase准备工作
环境 node>= 4.0 npm>= 3.0 rnpm (only if React Native version < 0.29) ReactNativeCLI 安装及运行 ht ...
- nginx - KeepAlive详细解释
最近工作中遇到一个问题,想把它记录下来,场景是这样的: 从上图可以看出,用户通过Client访问的是LVS的VIP, VIP后端挂载的RealServer是Nginx服务器. Client可以是浏览器 ...
- Erlang 在erlang项目中使用protobuf
protobuf是google的一个序列化框架,类似XML,JSON,其特点是基于二进制,比XML表示同样一段内容要短小得多,还可以定义一些可选字段,广泛用于服务端与客户端通信.文章将着重介绍在erl ...
- linux查看磁盘挂载的三种方法
第一种方法:使用df命令,例如: orientalson:/home # df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda ...
- 【PHP开发】用curl向https发请求时的35号错误
放了个假发现以前写的程序的模拟登陆不管用了,中间输出,发现curl向https发请求时没有返回数据,输出错误信息,得到: curl_errno($ch) -----> 35 curl_error ...
- 真正入坑git
之前使用git一直用sourceTree可视化操作,直到今天刚好装不了sourceTree,所有只能苦逼的用git命令行了,真的一片空白,要做下笔记才行. 创建sshKey 创建ssh: ssh-ke ...