• CF796C Bank Hacking


    题目链接

    分析

    题目好长
    其实也不是很长,我感觉按照原题的说法去理解这个题会比较好理解一些。
    就是说,我先从树上找到一个点,然后一步一步的去覆盖这棵树,你只能覆盖点权比你小的点,问覆盖整棵树需要你的权值最小是多少。
    首先先考虑我会去从哪个点开始,显然是先覆盖点权大的,因为它迟早都要被覆盖,如果现在不去覆盖,那再覆盖它,它的点权就会增加,所以肯定要先覆盖点权大的,进而可以知道,一个点如果有可能成为最大值,它的点权最多只会被+2,因为我要去覆盖它,首先覆盖它的半相邻点,再去覆盖它的相邻点,
    如果它变大了,那我下一步就要把它覆盖掉,因此答案最多只可能是最大值+2。
    接下来就是一个分类讨论了,假设最大值为(max),我们只要找(max-1)的点就行了,因为(max-2)的点最多也只会被搞成(max),如果所有的(max-1)的点都连在(max)上,那我搞完(max)就能在他们增加1到(max-1+1)的时候,破坏掉他们,所以此时答案为(max),如果一个(max-1)的点也没有,那答案显然也是这个。

    如果他们不连在一起呢?

    那我覆盖(max)和6的时候,(max-1)都要+1,最后就成了(max+1),所以当没有连在一起的时候,就是(max+1)
    那么有不止一个(max)的时候呢?

    如果这些都连在一起,答案是(max+1),不管是连在(max)上还是别的上边,只要他们互为相邻点或半相邻点就好。

    那么跟上边推(max-1)的时候一样,只不过(max)最多变成(max+2)
    也就这几种情况了,模拟一下就出来??

    #include<cstdio>
    #include<limits>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int N=3e5+10;
    struct Edge{
        int to,nxt;
    }e[N<<1];
    int h[N],idx,w[N];
    void Ins(int a,int b){
        e[idx].to=b;e[idx].nxt=h[a];h[a]=idx++;
    }
    int main(){
        memset(h,-1,sizeof(h));
        int n,mx,cnt,cntsec,pos;
        mx=INT_MIN;cntsec=cnt=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++){
            scanf("%d",&w[i]);
            if(w[i]>mx){
                mx=w[i];
                pos=i;
            }
        }
        for(int i=1;i<=n;i++){
            if(w[i]==mx)cnt++;
            if(w[i]==mx-1)cntsec++;
        }
        for(int i=1;i<n;i++){
            int a,b;
            scanf("%d%d",&a,&b);
            Ins(a,b);
            Ins(b,a);
        }
        if(cnt==1){
            if(cntsec==0){
                printf("%d
    ",mx);
                return 0;
            }
            int nxt=0;
            for(int i=h[pos];~i;i=e[i].nxt){
                if(w[e[i].to]==mx-1)nxt++;
            }
            if(nxt==cntsec)
                printf("%d
    ",mx);
            else printf("%d
    ",mx+1);
            return 0;
        }
        if(cnt>1){
            for(int i=1;i<=n;i++){
                int nxt=0;
                for(int j=h[i];~j;j=e[j].nxt){
                    if(w[e[j].to]==mx)nxt++;
                }
                if((nxt==cnt&&w[i]!=mx)||(nxt==cnt-1&&w[i]==mx)){
                    printf("%d
    ",mx+1);
                    return 0;
                }
            }
        }   
        printf("%d
    ",mx+2);
        return 0;
    }
    
  • 相关阅读:
    将Nginx添加到windows服务中
    springboot使用redis管理session
    GIT常用命令
    阻止360、谷歌浏览器表单自动填充
    谈谈对Spring IOC的理解
    同一个Nginx服务器同一端口配置多个代理服务
    LeetCode 653. Two Sum IV
    109. Convert Sorted List to Binary Search Tree(根据有序链表构造平衡的二叉查找树)
    108. Convert Sorted Array to Binary Search Tree(从有序数组中构造平衡的BST)
    LeetCode 236. Lowest Common Ancestor of a Binary Tree(二叉树求两点LCA)
  • 原文地址:https://www.cnblogs.com/anyixing-fly/p/12806827.html
Copyright © 2020-2023  润新知