• 洛谷P3237 米特运输


    题目链接

    题意:

      中文题,挺好理解。就是让节点的权值等于各子节点权值之和,然后每个子节点的权值相等,原本每个点有一个权值,通过最少次的修改(可以修改成小数)使其满足要求。

    分析:

      题意一旦读明白,题什么的就简单起来了。。。首先,我们这样思考,如果我要让x节点权值不变,那么其他节点的权值都能求处来,然后判断有几个相等的就可以了,只不过是这样的话枚举节点要n次dfs,所有我们换一种思路,如果这个节点和某个节点可以“互存”(同时不改变权值),那么他们使得根的最后的值将会是一样的,反过来说,他们使得的根的值一样,那么他们可以互存也是对的(即这两句话等价),然后我们就可以直接判断不变x根节点的值将会是多少,怎么判断呢,只要判断从这里到根节点要乘多少(这个数字比较好算),然后再乘上本身的权值,只是这样下去爆long long,没有关系,换python解决问题。。。开玩笑的。。。,取个对数就好了。然后最后的答案就是n-可以“共存”的最多的节点。

      然后就是代码

    #include <cstdio>
    #include <algorithm>
    #include <cmath>
    using namespace std;
    const int maxn=500000+10;
    double v[maxn];
    double f[maxn];
    struct E{
        int to;
        int next;
        E(){
            to=next=0;
        }
    }ed[maxn*2];
    int head[maxn];
    int tot;
    void J(int a,int b){
        tot++;
        ed[tot].to=b;
        ed[tot].next=head[a];
        head[a]=tot;
    }
    double son[maxn];
    void Dfs(int x,int fa){
        f[x]=son[fa]+f[fa];
        for(int i=head[x];i;i=ed[i].next){
            if(ed[i].to==fa)
                continue;
            son[x]+=1;
        }
        son[x]=log(son[x]);
        for(int i=head[x];i;i=ed[i].next)
            if(ed[i].to!=fa)
                Dfs(ed[i].to,x);
    }
    double ans[maxn];
    long long ans_1[maxn];
    long long ans_2[maxn];
    int ans_3[maxn];
    int ha[maxn];
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&v[i]);
        int js1,js2;
        for(int i=1;i<=n-1;i++){
            scanf("%d%d",&js1,&js2);
            J(js1,js2);
            J(js2,js1);
        }
        Dfs(1,0);
        for(int i=1;i<=n;i++){
            v[i]=log(v[i]);
            ans[i]=f[i]+v[i];
            ans_1[i]=ans_2[i]=ans[i]*1e6;//精度的处理
        }
        sort(ans_2+1,ans_2+1+n);//离散化
        int gs=unique(ans_2+1,ans_2+1+n)-ans_2-1;
        for(int i=1;i<=n;i++)
            ans_3[i]=lower_bound(ans_2+1,ans_2+1+gs,ans_1[i])-ans_2;
        for(int i=1;i<=n;i++)
            ha[ans_3[i]]++;
        int ma=0;
        for(int i=1;i<=gs;i++)
            ma=max(ha[i],ma);
        printf("%d",n-ma);
        return 0;
    }
  • 相关阅读:
    Redis 记录
    flink 流控机制详解
    备份和快照的区别
    LVS 总结
    Keepalived 总结
    OpenResty 总结
    Lua 总结
    Element-UI 总结
    Java transient 关键字
    Activiti 框架
  • 原文地址:https://www.cnblogs.com/wish-all-ac/p/12775860.html
Copyright © 2020-2023  润新知