• 【模拟】CF 796C Bank Hacking


    题目大意

    洛谷链接
    给定一棵带点权树,选出一个最佳的根节点,使得根节点的点权不变,它的儿子点权加1,其余点点权加2,并使最大点权最小,输出这个最小的最大点权。
    其他见链接(懒)。
    PS:原题面很不好总结题意,洛谷的翻译的确很清楚。

    思路

    先枚举最大点权设为(v_{max})

    • 若最大点权的点只有一个
      • 若没有(v=v_{max}-1)的点,答案即为(v_{max})
      • 若存在且为最大权值点的子节点,答案为(v_{max}-1+1=v_{max})
      • 若存在且不是最大权值点的子节点,答案为(v_{max}-1+2=v_{max}+1)
    • 若最大点权的点不止一个
      • 若其他最大点权的点都是一个最大点权的点的子节点,答案为(v_{max}+1)
      • 若所有最大点权的点都是一个点的子节点,答案为(v_{max}+1)
      • 若都不是,则答案为(v_{max}+2)

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=300000+10;
    const int INF=0x3f3f3f3f;
    struct node{
        int to,nxt;
    }e[maxn*2];
    int n,ans,vmax=-INF,a[maxn];
    bool flag;
    map<int,int> mp;//不能用数组!否则会RE,因为存在负权
    
    int cnt,head[maxn];
    void add(int x,int y){
        e[++cnt].to=y;
        e[cnt].nxt=head[x];
        head[x]=cnt;
    }
    
    int main(){
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&a[i]);
            mp[a[i]]++;//记录权值出现次数
            vmax=max(vmax,a[i]);//找最大点权
        }
    
        ans=vmax+2;
        for(int i=1;i<n;i++){
            int x,y;
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
    
        for(int i=1;i<=n;i++){
            flag=0;
            for(int j=head[i];j;j=e[j].nxt){
                mp[a[e[j].to]]--;//儿子权值次数--
                if(a[e[j].to]==vmax)flag=1;//flag为1表示儿子中有最大权值
            }
            if(!mp[vmax])ans=vmax+1;//所有最大权值点都是一个点的儿子
            if(vmax==a[i]&&mp[vmax]==1){//最大值是根
                if(mp[vmax-1])ans=vmax+1;//存在非儿子的权值为vmax-1的点,加2,得到的是vmax+1
                else if(flag)ans=vmax+1;//儿子中有最大权值,加一就是最大了
                else{
                    ans=vmax;//根是最大值
                    break;
                }
            }
            for(int j=head[i];j;j=e[j].nxt)
                mp[a[e[j].to]]++;//再加回来
        }
    
        printf("%d
    ",ans);//以上都没有更新,就是vmax+2的情况
        return 0;
    }
    
  • 相关阅读:
    Android Logcat使用技巧
    SqlClient使用存储过程并获取输出参数的指
    内存调试的东西D/dalvikvm( 809 ): GC_CONCURRENT freed
    android 读写sd卡的权限设置
    Android中EditText的使用方法持續更新
    RSL编译方式的FLEX站点出现#2046错误
    从网络读取数据并动态的显示在ListView中
    LEFT JOIN INNER JOIN 效率比较
    使用Installshield2009 在IIS6部署Asp.net mvc 应用程序
    Installshield2009中使用osql.exe执行数据库脚本
  • 原文地址:https://www.cnblogs.com/Midoria7/p/12807003.html
Copyright © 2020-2023  润新知