BZOJ 1196 二分答案+并查集

http://www.lydsy.com/JudgeOnline/problem.php?id=1196

题目大意:n个城市,m-1条路,每条路有一级公路和二级公路之分,你要造n-1条路,一级公路至少要造k条,求出所造路的最大所需的val的最小值.

思路:首先我们一定要明确这个不是一题求所有花费的最小值的问题。然后我们只要二分答案就可以了。最后注意一下条件的拜访即可。

//看看会不会爆int!数组会不会少了一维!
//取物问题一定要小心先手胜利的条件
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define ALL(a) a.begin(), a.end()
#define pb push_back
#define mk make_pair
#define fi first
#define se second
const int maxn = + ;
const int inf = 0x3f3f3f3f;
struct Edge{
int u, v, val1, val2;
Edge(int u = , int v = , int v1 = , int v2 = ): u(u), v(v), val1(v1), val2(v2){}
bool operator < (const Edge &a) const{
if (val1 != a.val1) return val1 < a.val1;
return val2 < a.val2;
}
}e[maxn * ];
int n, k, m;
int par[maxn];
int pfind(int x){
if (par[x] == x) return x;
return par[x] = pfind(par[x]);
} bool judge(int midval){
for (int i = ; i <= n; i++) par[i] = i;
int cnt1 = , cnt = ;
for (int i = ; i <= m - ; i++){
Edge a = e[i];
int pu = pfind(a.u), pv = pfind(a.v);
if (pu == pv) continue;
if (a.val1 <= midval) cnt1++, cnt++, par[pu] = pv;
else if (a.val2 <= midval) cnt++, par[pu] = pv;
}
if (cnt == n- && cnt1 >= k) return true;
return false;
} int main(){
scanf("%d%d%d", &n, &k, &m);
int lb = , rb = ;
for (int i = ; i <= m - ; i++){
int u, v, v1, v2;
scanf("%d%d%d%d", &u, &v, &v1, &v2);
e[i] = Edge(u, v, v1, v2);
}
sort(e + , e + m);
while (lb < rb){
int mid = lb + (rb - lb) / ;
if (judge(mid)){
rb = mid;
}
else {
lb = mid + ;
}
}
printf("%d\n", lb);
return ;
}
/*
3 1 3
1 2 11 4
2 3 10 2
*/
上一篇:Nutch2.2.1在MyEclipse中的安装(window7环境)


下一篇:JavaWeb项目开发案例精粹-第2章投票系统-003Dao层