码迷,mamicode.com
首页 > 其他好文 > 详细

[国家集训队2]Tree I

时间:2018-11-05 14:01:22      阅读:165      评论:0      收藏:0      [点我收藏+]

标签:while   生成   etc   lse   tps   ios   总结   http   new   

题意

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

标签:while   生成   etc   lse   tps   ios   总结   http   new   

原文地址:https://www.cnblogs.com/alecli/p/9908721.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!