zoukankan      html  css  js  c++  java
  • bzoj 2799 [Poi2012]Salaries 性质+二分

    题目大意

    给出一棵n个结点的有根树,结点用正整数1~n编号。
    每个结点有一个1~n的正整数权值,不同结点的权值不相同,
    并且一个结点的权值一定比它父结点的权值小(根结点的权值最大,一定是n)。
    现在有些结点的权值是已知的,并且如果一个结点的权值已知,它父结点的权值也一定已知。
    问还有哪些结点的权值能够唯一确定。
    最后输出每个点的全值,不知道输出0
    n<=1,000,000

    分析

    我们求出每个点最大可以是什么权值
    如果i点权值<=d,而<=d中的权值已经确定了d-1个,那么i的权值也可以确定
    按照贪心,我们从小到大填权值

    做法

    求每个点最大权值就dfs+二分
    后面选数就按权值从小到大扫就可以了

    solution

    #include <cstdio>
    #include <cstring>
    #include <cstdlib>
    #include <cctype>
    #include <cmath>
    #include <algorithm>
    using namespace std;
    const int M=1000007;
     
    inline int rd(){
        int x=0;bool f=1;char c=getchar();
        for(;!isdigit(c);c=getchar()) if(c=='-') f=0;
        for(;isdigit(c);c=getchar()) x=x*10+c-48;
        return f?x:-x;
    }
     
    int n,rt;
    int g[M],te;
    struct edge{int y,next;}e[M];
    int vis[M];
    int val[M];
    int pre[M];
    int a[M],tot;
     
    struct node{
        int d,id;
        node (int dd=0,int ii=0){d=dd;id=ii;}
    }b[M];
    int num;
     
    bool cmp(node x,node y){return x.d<y.d;}
     
    void addedge(int x,int y){
        e[++te].y=y;e[te].next=g[x];g[x]=te;
    }
     
    int find(int d){
        int l=1,r=tot,mid;
        while(l<r){
            int mid=(l+r)/2+1;
            if(a[mid]>=d) r=mid-1;
            else l=mid;
        }
        return a[l];
    }
     
    void dfs(int x,int mx){
        if(val[x]) mx=val[x];
        else {
            mx=find(mx);
            b[++num]=node(mx,x);
        }
        int p,y;
        for(p=g[x];p;p=e[p].next)
        if((y=e[p].y)!=pre[x]){
            dfs(y,mx);
        }
    }
     
    int main(){
        int i,j,x,y,z;
        n=rd();
        for(i=1;i<=n;i++){
            y=rd(),z=rd();
            if(i==y) rt=i;
            else pre[i]=y,addedge(y,i);
            val[i]=z;
            vis[z]=1;
        }
         
        for(i=1;i<=n;i++)
            if(!vis[i]) a[++tot]=i;
         
        dfs(rt,n);
         
        sort(b+1,b+num+1,cmp);
         
        int cnt=0;
        j=1;
        for(i=1;i<=n;i++){
            if(vis[i]){
                cnt++;
                continue;
            }
            if(b[j].d==i){
                int tp=j;
                for(;j<=num&&b[j].d==i;j++);
                if(cnt==i-1) val[b[j-1].id]=i;
                cnt+=j-tp;
            }
        }
         
        for(i=1;i<=n;i++) printf("%d
    ",val[i]);
         
        return 0;
    }
    
  • 相关阅读:
    Spring 集成 MemCache
    memCachedClient 客户端调用时注意的问题,坑
    二)spring 集成 ehcache jgroups 集群
    三)mybatis 二级缓存,整合ehcache
    四)mybatis 二级缓存 ehcache 常见问题
    都有哪些 cache ?
    【转】高并发的核心技术-幂等的实现方案
    如何学习一门编程语言
    WebService学习记录
    代理
  • 原文地址:https://www.cnblogs.com/acha/p/6407320.html
Copyright © 2011-2022 走看看