BZOJ2799/POI2012 Salaries

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

Solution
根据树的结构,我们可以对每个没有确定大小的点i列出一个不等式:zi<=xi
那么只要按照xi从小到大排序,若考虑点i时只有一个数字可选,那么zi就是唯一的.假如有k个点的xi相同,(当k>1时,它们的zi都无法确定)在备选的所有值中把前k个值删去即可.

#include<cstring>
#include<cstdio>
#include<algorithm>
#include<iostream>
using namespace std;
const int M=1e6+5;
int mark[M],rt,ec=0,head[M],n,A[M],Bit[M],C[M],dep[M],tot=0,m=0;
struct node{
    int to,nex;
    bool operator<(const node &tmp)const{
        return nex<tmp.nex;
    }
}e[M<<1],B[M];
inline void rd(int &res){
    res=0;char c;
    while(c=getchar(),c<48);
    do res=(res<<1)+(res<<3)+(c^48);
    while(c=getchar(),c>=48);
}
inline void print(int k){
    if(!k)return;
    print(k/10);
    putchar(k%10^48);
}
inline void sc(int k){
    if(k<0){k=-k;putchar('-');}
    print(k);
    if(k==0)putchar('0');
    putchar('\n');
}
void ins(int a,int b){
    e[ec]=(node){a,head[b]};
    head[b]=ec++;
    e[ec]=(node){b,head[a]};
    head[a]=ec++;
}
void dfs(int x,int f,int a,int d){//a 
    dep[x]=d;
    if(A[x])a=A[x];
    else{
        B[++tot]=(node){x,upper_bound(C,C+m,a-1)-C-1};
        a=C[B[tot].nex];
    }
    for(int i=head[x];~i;i=e[i].nex){
        int y=e[i].to;
        if(y==f)continue;
        dfs(y,x,a,d+1);
    }
}
int main(){
    int a,b,i,j,k;
    rd(n);
    memset(head,-1,sizeof(head));
    for(i=1;i<=n;i++){
        rd(a);rd(A[i]);
        if(A[i])mark[A[i]]=1;
        if(i!=a)ins(i,a);
        else rt=i;
    }
    A[rt]=n;
    mark[n]=rt;
    for(i=1;i<=n;i++){
        if(!mark[i])C[m++]=i;//还可选的数字 
    }
    dfs(rt,rt,rt,1);
    sort(B+1,B+1+tot);
    sort(C,C+m);
    k=0;
    for(i=1;i<=tot;i=j){
        j=i;
        while(j<=n&&B[j].nex==B[i].nex)j++;
        if(j-i==1){//B[j].nex就是最后大于的数字 
            if(B[i].nex==k)A[B[i].to]=C[k++];
            else k++;
        }
        else{
            k+=j-i;//
        }
    }
    for(i=1;i<=n;i++)sc(A[i]);
    return 0;
}

展开阅读全文

没有更多推荐了,返回首页