[HNOI/AHOI2018]排列

[Luogu4437]

如果\(a[i]=j\)则序列\(p[]\)中\(j\)必须排在\(i\)前面,如果\(j\)不在范围内则不管,求一个式子\(\sum_{i=1}^n iw_{p[i]}\)的最大值

考虑建出一个图,连边\(k=a_j\to j\)方向表示顺序,这样\([1,n]\)每个点的入度都会是\(1\)

如果有环那么就无解,否则这个图就是一棵以\(0\)为根树,如果是在树上的话,也就是说必须要先选父亲才能选儿子

考虑一种贪心

考虑一个当前权值最小的点\(i\)
\(1.\)如果\(i\)没有父亲\((fa[i]=0)\),那么我们当前一定是选\(i\)
\(2.\)如果\(i\)有父亲,那么当\(fa[i]\)选了后我们一定会最先选\(i\)
也就是说在最后的排列中\(fa[i]\)和\(i\)是挨在一块的,但是考虑到实际上多次合并后每个节点就是一个序列

手模以后发现,平均权值小的放前面答案会更优

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cassert>
#define debug(...) fprintf(stderr,__VA_ARGS__)
#define Debug(x) cout<<#x<<"="<<x<<endl
using namespace std;
typedef long long LL;
typedef long double ld;
const int INF=1e9+7;
typedef pair<ld,int> pdi;
inline LL read(){
    register LL x=0,f=1;register char c=getchar();
    while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
    while(c>=48&&c<=57)x=(x<<3)+(x<<1)+(c&15),c=getchar();
    return f*x;
}

const int MAXN=5e5+5;

LL w[MAXN],done[MAXN];
int Fa[MAXN],a[MAXN];
int n;LL ans;
priority_queue <pdi,vector<pdi>,greater<pdi> > q,t;

inline int getfa(int x){return Fa[x]==x?x:Fa[x]=getfa(Fa[x]);}

int main(){
    n=read();
    for(int i=1;i<=n;i++) Fa[i]=i;
    for(int i=1;i<=n;i++){
        a[i]=read();
        int fx=getfa(i),fy=getfa(a[i]);
        if(fx==fy){printf("-1\n");return 0;}
        Fa[fx]=fy;//直接用并查集判环
    }
    for(int i=1;i<=n;i++)
        ans+=(w[i]=read());//先加一遍
    for(int i=0;i<=n;i++) Fa[i]=i;
    for(int i=1;i<=n;i++){
        done[i]=1;
        q.push(pdi((ld)w[i],i));
    }
    for(int i=1;i<=n;i++){
        while(!t.empty()&&q.top()==t.top()){//每次删掉q.top(),可以保证正确性
            t.pop();q.pop();
        }
        int x=q.top().second;q.pop();
        assert(x==Fa[x]);
        int y=getfa(a[x]);
        if(y) t.push(pdi((ld)w[y]*1.0/done[y],y));//删掉
        ans+=w[x]*done[y];//之前已经选了多少个,现在就接着选
        w[y]+=w[x],done[y]+=done[x],Fa[x]=y;//合并个数到上一层(y可以等于0)
        if(y) q.push(pdi((ld)w[y]*1.0/done[y],y));//更新
    }
    printf("%lld\n",ans);
}
上一篇:【[HNOI/AHOI2018]毒瘤】


下一篇:[HNOI/AHOI2018]毒瘤