zoukankan      html  css  js  c++  java
  • [LOJ3052] [十二省联考 2019] 春节十二响

    题目链接

    LOJ:https://loj.ac/problem/3052

    洛谷:https://www.luogu.org/problemnew/show/P5290

    BZOJ:https://www.lydsy.com/JudgeOnline/problem.php?id=5499

    Solution

    部分分有一个链的情况极大的提示了正解。

    考虑链情况怎么做,显然是(1)号节点向下延伸出了两条支链,那么我们可以分别( m sort)然后最大的和最大的成对,次打的同理,这样显然是最优的。

    那么我们考虑二叉树怎么做,同样对于点(x)我们开一个堆记录这个点的子树的使用信息,那么点(x)可以通过两个儿子按照链情况一样的合并得到。

    普通的树同理,如果我们加一个启发式合并就可以做到(O(nlog n))

    注意启发式合并的时候有一个( m swap)堆的过程,这玩意在( m BZOJ)好像会发生奇怪的错误反正窝是MLE了,所以我们记个编号就好了。好像原因是因为BZOJ不支持c++11...

    #include<bits/stdc++.h>
    using namespace std;
    
    void read(int &x) {
        x=0;int f=1;char ch=getchar();
        for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
        for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
    }
    
    #define ll long long 
    
    void print(ll x) {
        if(x<0) putchar('-'),x=-x;
        if(!x) return ;print(x/10),putchar(x%10+48);
    }
    void write(ll x) {if(!x) putchar('0');else print(x);putchar('
    ');}
    
    #define lf double
    
    #define pii pair<int,int >
    #define vec vector<int >
    
    #define pb push_back
    #define mp make_pair
    #define fr first
    #define sc second
    
    const int maxn = 2e5+10;
    const int inf = 1e9;
    const lf eps = 1e-8;
    
    int head[maxn],tot,n,a[maxn],sta[maxn],top,id[maxn];
    struct edge{int to,nxt;}e[maxn<<1];
    
    priority_queue<int > s[maxn];
    
    void add(int u,int v) {e[++tot]=(edge){v,head[u]},head[u]=tot;}
    void ins(int u,int v) {add(u,v),add(v,u);}
    
    void dfs(int x,int fa) {
        for(int v,i=head[x];i;i=e[i].nxt) {
            if((v=e[i].to)==fa) continue;top=0;dfs(v,x);
            if(s[id[v]].size()>s[id[x]].size()) swap(id[x],id[v]);
            while(s[id[v]].size()) sta[++top]=max(s[id[x]].top(),s[id[v]].top()),s[id[x]].pop(),s[id[v]].pop();
            while(top) s[id[x]].push(sta[top--]);
        }s[id[x]].push(a[x]);
    }
    
    int main() {
        read(n);for(int i=1;i<=n;i++) read(a[i]),id[i]=i; 
        for(int i=2,x;i<=n;i++) read(x),ins(i,x);
        dfs(1,0);ll ans=0;while(s[id[1]].size()) ans+=(ll)s[id[1]].top(),s[id[1]].pop();
        write(ans);
        return 0;
    }
    
  • 相关阅读:
    蓝桥杯 算法训练 ALGO-118 连续正整数的和
    迭代器和生成器
    字符串格式化
    python 赋值 深浅拷贝
    web.py
    urlib2 标准代码
    left menu
    tab menu
    modal html
    emmet使用
  • 原文地址:https://www.cnblogs.com/hbyer/p/10761097.html
Copyright © 2011-2022 走看看