E - Lomsat gelral

思路參考網上的

不用啓發式合併的話,會爆內存
Memory limit exceeded on test 26

小的去合併大的。。。
其實主要就是代碼中標記的那段

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <bitset>
#include <map>

#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define ROF(i,a,b) for(int i=a;i>=b;i--)
#define mem(i,a) memset(i,a,sizeof(i))
#define rson mid+1,r,rt<<1|1
#define lson l,mid,rt<<1

#define mp make_pair
#define pb push_back
#define ll long long
#define LL long long
using namespace std;
template <typename T>inline void read(T &_x_){
    _x_=0;bool f=false;char ch=getchar();
    while (ch<'0'||ch>'9') {if (ch=='-') f=!f;ch=getchar();}
    while ('0'<=ch&&ch<='9') {_x_=_x_*10+ch-'0';ch=getchar();}
    if(f) _x_=-_x_;
}
const double eps = 0.0000001;
const int maxn = 1e5+7;
const int mod = 1e9+7;

int n,x,y;
int w[maxn];
ll ans[maxn],ma[maxn],mh[maxn];
map<int ,int> mmp[maxn];
vector<int> v[maxn];

void dfs(int u,int fa){
    ma[u]=1;
    mh[u]=w[u];
    mmp[u][w[u]]++;
    for(int now:v[u]){
        if(now==fa) continue;
        dfs(now,u);
        if(mmp[u].size()<mmp[now].size()){     //這個if是核心
            swap(mmp[u],mmp[now]);
            swap(ma[u],ma[now]);
            swap(mh[u],mh[now]);
        }
        for(auto it=mmp[now].begin();it!=mmp[now].end();it++){
            int fi = it->first;
            int se = it->second;
            mmp[u][fi]+=se;
            if(mmp[u][fi]==ma[u]) mh[u]+=fi;
            if(mmp[u][fi]>ma[u]){
                ma[u] = mmp[u][fi];
                mh[u] = fi;
            }
        }
    }
    ans[u]=mh[u];
}

int main(){
    read(n);
    FOR(i,1,n) scanf("%d",&w[i]);
    FOR(i,2,n){
        read(x),read(y);
        v[x].pb(y);
        v[y].pb(x);
    }
    dfs(1,0);
    FOR(i,1,n) printf("%I64d ",ans[i]);
    printf("\n");
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章