BZOJ 1196 HNOI 2006 公路修建问题 二分答案+并查集

题目大意:给出n个点,要求把它们连成一棵树,有一些边可供选择,每一条遍都有一级公路和二级公路,问在一级公路不少于k的情况下最高花费的最低值是多少。

思路:二分答案,然后验证的时候先将边按照一级公路的权值从大到小排序,我们每一次验证应该尽可能的选择能选的一级公路,如果一级公路不能选,看二级公路能不能选,如果。最后看一级公路选择的数量和总的公路选择的数量。

CODE:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define MAX 20010
using namespace std;

struct Edge{
	int x,y;
	int cost,_cost;

	bool operator <(const Edge &a)const {
		return cost < a.cost;
	}
	void Read() {
		scanf("%d%d%d%d",&x,&y,&cost,&_cost);
	}
}edge[MAX];

int points,k,edges;
int father[MAX];

int Find(int x)
{
	if(father[x] == x)	return x;
	return father[x] = Find(father[x]);
}

inline bool Judge(int ans)
{
	for(int i = 1; i <= points; ++i)
		father[i] = i;
	int first = 0,added = 0;
	for(int i = 1; i <= edges; ++i) {
		int fx = Find(edge[i].x);
		int fy = Find(edge[i].y);
		if(fx != fy) {
			if(edge[i].cost <= ans) {
				++first,++added;
				father[fx] = fy;
			}
			else if(edge[i]._cost <= ans) {
				++added;
				father[fx] = fy;
			}
		}
	}
	return first >= k && added == points - 1;
}

int main()
{
	cin >> points >> k >> edges;
	for(int i = 1; i <= edges - 1; ++i)
		edge[i].Read();
	sort(edge + 1,edge + edges + 1);
	int l = 0,r = 30000,ans = 30000;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(Judge(mid))
			ans = mid,r = mid - 1;
		else	l = mid + 1;
	}
	cout << ans << endl;
	return 0;
}
时间: 2024-10-05 04:19:11

BZOJ 1196 HNOI 2006 公路修建问题 二分答案+并查集的相关文章

[BZOJ 1196][HNOI 2006]公路修建问题

题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1196 可以说这是个瓶颈生成树的题? 不算很难的图论题,构思非常巧妙... 二分生成树的最大边权x,判断这样的生成树是否存在就行了... 每次判断时分成两步走,首先要限制c1小于等于x,判断生成树中的树边个数是否小于等于k,若大于k,表明这个生成树不存在. 再限制c2小于等于x,由于c2<c1,所以这时候c1不用管了,能加进去的边都加进去,加完边后判断生成树的树边是不是n-1(生成

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

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1196 [题目大意] 对于每条可能维修的公路可选择修一级公路或者二级公路,价值不同 要求图连通,且至少有k条一级公路时最大价值公路价值最小. [题解] 二分答案,从一级公路开始处理,利用并查集验证两个条件. [代码] #include <cstdio> #include <algorithm> using namespace std; const int N=20005;

BZOJ 1196 HNOI2006 公路修建问题 二分答案+Kruskal

题目大意:给定一个无向图,一条边可以被建为一级公路或二级公路,要求一级公路的数量不小于k条,求最小生成树 最小生成树保证的是最大边最小 直接对边排序,然后二分答案,每次用Kruskal验证 先连一级边看能不能连出k条,再连剩余的边看看能不能得到最小生成树 #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 10100 using nam

【BZOJ 1196】 [HNOI2006]公路修建问题

1196: [HNOI2006]公路修建问题 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1221  Solved: 661 [Submit][Status] Description OI island是一个非常漂亮的岛屿,自开发以来,到这儿来旅游的人很多.然而,由于该岛屿刚刚开发不久,所以那里的交通情况还是很糟糕.所以,OIER Association组织成立了,旨在建立OI island的交通系统. OI island有n个旅游景点,不妨

BZOJ 1196 二分答案+并查集

http://www.lydsy.com/JudgeOnline/problem.php?id=1196 题目大意:n个城市,m-1条路,每条路有一级公路和二级公路之分,你要造n-1条路,一级公路至少要造k条,求出所造路的最大所需的val的最小值. 思路:首先我们一定要明确这个不是一题求所有花费的最小值的问题.然后我们只要二分答案就可以了.最后注意一下条件的拜访即可. //看看会不会爆int!数组会不会少了一维! //取物问题一定要小心先手胜利的条件 #include <bits/stdc++.

HDU3081Marriage Match II(二分答案+并查集+最大流SAP)经典

Marriage Match II Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2507    Accepted Submission(s): 856 Problem Description Presumably, you all have known the question of stable marriage match. A

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

链接: https://vjudge.net/problem/HDU-3081 题意: Presumably, you all have known the question of stable marriage match. A girl will choose a boy; it is similar as the game of playing house we used to play when we are kids. What a happy time as so many frie

BZOJ 2654 tree(二分答案+并查集)

[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2654 [题目大意] 给你一个无向带权连通图,每条边是黑色或白色. 让你求一棵最小权的恰好有need条白色边的生成树.题目保证有解. [题解] 我们发现对于选中的边白色是从小到大的,黑色也是从小到大的, 因此我们对所有的白色边加一个权值,那么排序后做mst选取的白色边数量增减性单调, 对于增加的权值进行二分,验证能否满足要求即可. [代码] #include <cstdio> #in

【bzoj3007】拯救小云公主 二分+对偶图+并查集

题目描述 英雄又即将踏上拯救公主的道路…… 这次的拯救目标是——爱和正义的小云公主. 英雄来到boss的洞穴门口,他一下子就懵了,因为面前不只是一只boss,而是上千只boss.当英雄意识到自己还是等级1的时候,他明白这就是一个不可能完成的任务. 但他不死心,他在想,能不能避开boss去拯救公主呢,嘻嘻. Boss的洞穴可以看成一个矩形,英雄在左下角(1,1),公主在右上角(row,line).英雄为了避开boss,当然是离boss距离越远越好了,所以英雄决定找一条路径使到距离boss的最短距离