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\n",val[i]);
     
    return 0;
}
posted @ 2017-02-16 19:42  _zwl  阅读(290)  评论(0编辑  收藏  举报