zoukankan      html  css  js  c++  java
  • 「HNOI 2014」米特运输

    题目链接

    戳我

    (Describe)

    谁出的题目啊?这么长的题面,看完就滚粗了.强烈谴责

    给一棵树,每个点有一个权值,要求修改一些权值,使:

    1. 一个点的权值必须是其所有儿子的权值之和
    2. 一个点的儿子权值必须相同
      求最少的被修改的数目

    (Solution)

    随便画一画图就可以找到一些显著的规律,只要确定了一个点的权值就可以知道整颗树的值了.

    这里就不详细的给出图进行解释了,自己画一画图就可以知道了.

    于是我们可以令(val[x])表示(x)这个点不变的话,根节点的值.

    但是将子节点的个数成起来会爆(long long),所以需要运用一点小技巧:(log)

    运用公式:(log(a*b)=log(a)+log(b))

    答案就是(n-val)数组中相同个数最多的.

    (Code)

    #include<bits/stdc++.h>
    using namespace std;
    const double eps=1e-6;
    int read(){
        int x=0,f=1;char c=getchar();
        while(c<'0'||c>'9') f=(c=='-')?-1:1,c=getchar();
        while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar();
        return x*f;
    }
    struct node {
        int to,next;
    }a[500010<<1];
    double val[500010];
    int v[500010],head[500010],s[500010],cnt;
    void add(int x,int y){
        a[++cnt].next=head[x],a[cnt].to=y,head[x]=cnt;
        a[++cnt].next=head[y],a[cnt].to=x,head[y]=cnt;
    }
    void dfs(int x,int fa,double ans){
        val[x]=ans+log(v[x]),s[x]--;
        for(int i=head[x];i;i=a[i].next){
            int v=a[i].to;
            if(v==fa)
                continue;
            dfs(v,x,ans+log(s[x]));
        }
    }
    main(){
        int n=read(),x,y,maxx=0,js=1;
        for(int i=1;i<=n;i++)
            v[i]=read();
        for(int i=1;i<n;i++)
            x=read(),y=read(),add(x,y),s[x]++,s[y]++;
        s[1]++,dfs(1,0,0);
        sort(val+1,val+1+n);
        for(int i=2;i<=n;i++){
            if(val[i]-val[i-1]<eps)
                js++;
            else maxx=max(maxx,js),js=1;
        }
        printf("%d",n-maxx);
    }
    
  • 相关阅读:
    [蓝桥杯2017初赛]青蛙跳杯子 BFS
    第十一章 进程和信号
    第七章 数据管理
    特殊符号大全
    第四章 Linux环境
    (十六)异常
    (十五)代理
    (十四)内部类
    第三章 文件操作
    (十三)对象克隆
  • 原文地址:https://www.cnblogs.com/hbxblog/p/10396280.html
Copyright © 2011-2022 走看看