[国家集训队2]Tree I

Posted alecli

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[国家集训队2]Tree I相关的知识,希望对你有一定的参考价值。

题意

Here

思考

(WQS) 二分,第一次做,感觉细节有点多。

由于要求选 (need) 条白边,我们考虑每次给所有白边加上一个权值,再与黑边一起做生成树,这样就可以限制我们加入白边的个数了,但是这样我们还存在一个问题,如果有白边等于黑边权值,我们可能会先统计黑边,造成白边达不到 (need) 条的情况,我们只用在排序时加上第二关键字,优先选择白边即可。

代码


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int read(){
    int x=0,f=1;char ch=getchar();
    while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();}
    while(ch>=‘0‘&&ch<=‘9‘){x=x*10+ch-‘0‘;ch=getchar();}
    return x * f;
}
const int M = 100010;
const int N = 50050;
struct node{
    int from, to, dis, op, now;
}edge[M << 1];
bool cmp(node a, node b){
    return (a.now == b.now) ? a.op < b.op : a.now < b.now;
}
int fa[N];
int n, m, need, ans, sum, js;
int findx(int x){
    if(fa[x] == x) return x;
    return fa[x] = findx(fa[x]);
}
void mergex(int x, int y){
    int fx = findx(x), fy = findx(y);
    if(fx == fy) return;
    fa[fx] = fy;
}
bool check(int del){
    js = 0; sum = 0;
    for(int i=1; i<=n; i++) fa[i] = i;
    for(int i=1; i<=m; i++){
        edge[i].now = edge[i].dis;
        if(edge[i].op == 0) edge[i].now += del;
    }
    sort(edge+1, edge+m+1, cmp);
    for(int i=1; i<=m; i++){
        int u = edge[i].from, v = edge[i].to;
        int fu = findx(u), fv = findx(v);
        if(fu != fv){
            mergex(u, v); sum += edge[i].dis;
            if(edge[i].op == 0) js ++;
        }
    }
    return js >= need;
}
int main(){
    n = read(), m = read(), need = read();
    for(int i=1; i<=m; i++){
        edge[i].from = read(), edge[i].to = read(), edge[i].dis = read(), edge[i].op = read();
        edge[i].from ++, edge[i].to ++;
        if(edge[i].op == 1) edge[i].now = edge[i].dis;
    }
    int l = -100, r = 100;
    while(l <= r){
        int mid = (l + r) >> 1;
        if(check(mid)){
            l = mid + 1;
            ans = sum;
        }
        else r = mid - 1;
    }
    cout<<ans;
    return 0;
}

总结

注意二分的判断条件是大于等于 (need) ,以及排序时注意第二关键字以避免无法出解。

以上是关于[国家集训队2]Tree I的主要内容,如果未能解决你的问题,请参考以下文章

P2619 [国家集训队]Tree I(wqs二分)

P2619 [国家集训队]Tree I(wqs二分)

[国家集训队]Tree II

[国家集训队2012]tree(伍一鸣)

题解 luogu P1501[国家集训队]Tree II(Link-Cut-Tree)

洛谷 P1501 [国家集训队]Tree II