月出皎兮,佼人僚兮。

月出皎兮,佼人僚兮。

https://ac.nowcoder.com/acm/contest/6037/F

如果颜色最多个数大于其它颜色之和,可以匹配的对数就是其它颜色之和,即其它颜色的都和颜色最多的两两匹配
反之,每个颜色都能找到匹配,因为其它颜色匹配后,剩下的只要不断拿出两个去拆已经匹配了的一对,一定能用完。

MyCode:

#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+7,maxm=4e5+7;
typedef long long ll;
inline ll read(){
    ll s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}
int head[maxn],Next[maxm],to[maxm],tot;
void add(int x,int y) {
    to[++tot]=y;
    Next[tot]=head[x];
    head[x]=tot;
}
int size[maxn],son[maxn];
int ans[maxn],cnt[maxn],col[maxn],sum[maxn],num,maxx;
bool vis[maxn];
bool cmp(int &a,int &b) {
    return cnt[a]>cnt[b];
}
void dfs(int x,int f) {
    size[x]=1;
    for(int i=head[x],y=to[i];i;i=Next[i],y=to[i]) {
        if(y==f) continue;
        dfs(y,x);    size[x]+=size[y];
        if(size[son[x]]<size[y]) son[x]=y;
    }
}
void calc(int x,int f) {
    cnt[col[x]]+=sum[x];
    num+=sum[x]; if(cnt[col[x]]>maxx) maxx=cnt[col[x]];
    for(int i=head[x],y=to[i];i;i=Next[i],y=to[i]) {
        if(y==f||vis[y]) continue;
        calc(y,x);
    }
}
void delet(int x,int f) {
    cnt[col[x]]-=sum[x];
    for(int i=head[x];i;i=Next[i]) if(to[i]!=f) delet(to[i],x);
}
void dsu(int x,int f,bool opt) {
    for(int i=head[x],y=to[i];i;i=Next[i],y=to[i]) {
        if(y==f||son[x]==y) continue;
        dsu(y,x,false);
    }
    if(son[x]) {
        dsu(son[x],x,true);
        vis[son[x]]=true;
    }
    calc(x,f);
    if(num-maxx*2>=0) ans[x]=num/2;
    else ans[x]=num-maxx;
    if(son[x]) vis[son[x]]=false;
    if(!opt) {
        delet(x,f);
        num=maxx=0;
    }
}
int main() {
    int n=read();
    for(int i=2,u,v;i<=n;++i) {
        u=read(),v=read();
        add(u,v);
        add(v,u);
    }
    for(int i=1;i<=n;++i)  col[i]=read(),sum[i]=read();
    dfs(1,0);
    dsu(1,0,false);
    for(int i=1;i<=n;++i) printf("%d\n",ans[i]);
    return 0;
}
dsu on tree 文章被收录于专栏

启发式算法是什么呢? 启发式算法是基于人类的经验和直观感觉,对一些算法的优化。 适用于: 1.无修改操作,询问允许离线 2.对子树信息进行统计(链上的信息在某些条件下也可以统计) 也可以用莫队、点分治 但dsu on tree可以把它们吊起来打! dsu on tree运用树剖中的轻重链剖分,将轻边子树信息累加到重链上进行统计,拥有 O(nlogn) 的优秀复杂度,常数还贼小

全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务