首页 > 其他 > 详细

HDU5682 zxa and leaf(二分)

时间:2020-03-08 10:33:24      阅读:52      评论:0      收藏:0      [点我收藏+]

这道题很容易看出是求最大值的最小值,然后我们发现每个边的取值范围都是一段区间,这就是常见的用区间表示是否满足题意,当左边界大于右边界的时候就不满足

技术分享图片
#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<stack>
using namespace std;
typedef long long ll;
const int N=1e5+10;
const int inf=0x3f3f3f3f;
int n,k;
vector<int> g[N];
struct node{
    int l,r;
    int t1,t2;
}tr[N];
void init(){
    int i;
    for(i=0;i<=n;i++){
        tr[i].l=1;
        tr[i].r=inf;
        g[i].clear();
    }
}
bool dfs(int u,int fa,int x){
    tr[u].t1=tr[u].l;
    tr[u].t2=tr[u].r;
    int i;
    for(i=0;i<g[u].size();i++){
        int j=g[u][i];
        if(j==fa)
            continue;
        if(!dfs(j,u,x))
            return false;
        tr[u].t1=max(tr[u].t1,max(1,tr[j].t1-x));
        tr[u].t2=min(tr[u].t2,min(inf,tr[j].t2+x));
        if(tr[u].t1>tr[u].t2)
            return false;
    }
    return true;
}
bool check(int mid){
    return dfs(1,-1,mid);
}
int main(){
    int t;
    cin>>t;
    while(t--){
        cin>>n>>k;
        init();
        int i;
        for(i=0;i<n-1;i++){
            int u,v;
            scanf("%d%d",&u,&v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        for(i=0;i<k;i++){
            int u,w;
            scanf("%d%d",&u,&w);
            tr[u].l=tr[u].r=w;
        }
        int l=0,r=inf;
        while(l<r){
            int mid=l+r>>1;
            if(check(mid))
                r=mid;
            else
                l=mid+1;
        }
        cout<<l<<endl;
    }
}
View Code

 

HDU5682 zxa and leaf(二分)

原文:https://www.cnblogs.com/ctyakwf/p/12441162.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!