• 【codeforces 796C】Bank Hacking


    【题目链接】:http://codeforces.com/contest/796/problem/C

    【题意】

    给你n个节点,你一开始选择一个节点,然后打掉它,然后与被打掉过的节点相连的节点才能被
    打掉,但打掉一个点之后,与它距离小于等于2的节点的权值会增加1(如果中间节点有被打掉的,则不增加,即被切断了);
    重复上述步骤,直至所有节点被打掉,能打掉某个节点,你需要满足:你的权值大于等于这个节点的权值.求一开始你的
    权值的最小值;

    【题解】

    枚举每一个点作为第一个打掉的点,除了和它距离为1的那些点权值只递增1之外,其他点都会递增2,用multiset维护除了这个点和距离为1的点之外的点的权值的最大值
    用这个点权值a[i],距离为1的那些点的权值(a2[i]+1),以及multiset的(头结点的权值+2)这3个值中的最大值来获取你打掉所有节点且从第i个节点开始打需要的权值的最小值;
    对于第一次选取的点只选最大值是有漏洞的如
    3
    3 2 3
    1 2
    2 3
    选2的话答案更优为4
    选3则为5了

    【Number Of WA

    4

    【完整代码】

    #include <bits/stdc++.h>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define LL long long
    #define rep1(i,a,b) for (int i = a;i <= b;i++)
    #define rep2(i,a,b) for (int i = a;i >= b;i--)
    #define mp make_pair
    #define ps push_back
    #define fi first
    #define se second
    #define rei(x) scanf("%d",&x)
    #define rel(x) scanf("%lld",&x)
    #define ref(x) scanf("%lf",&x)
    #define ms(x,y) memset(x,y,sizeof x)
    
    typedef pair<int,int> pii;
    typedef pair<LL,LL> pll;
    
    const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
    const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
    const double pi = acos(-1.0);
    const int N = 3e5+100;
    
    int a[N],n,ans=21e8;
    vector <int> G[N];
    multiset<int,greater<int>> myset;
    
    void dele(int x)
    {
        __typeof(myset.begin()) t;
        t = myset.find(x);
        myset.erase(t);
    }
    
    int main()
    {
       // freopen("F:\rush.txt","r",stdin);
        rei(n);
        rep1(i,1,n)
            rei(a[i]),myset.insert(a[i]);
        rep1(i,1,n-1)
        {
            int x,y;
            rei(x),rei(y);
            G[x].ps(y),G[y].ps(x);
        }
        rep1(i,1,n)
        {
            dele(a[i]);
            int ma = a[i];
            for (int y:G[i])
            {
                dele(a[y]);
                ma = max(ma,a[y]+1);
            }
            if (!myset.empty())
                ma = max(ma,*myset.begin()+2);
            for (int y:G[i])
                myset.insert(a[y]);
            myset.insert(a[i]);
            ans = min(ans,ma);
        }
        printf("%d
    ",ans);
        //printf("
    %.2lf sec 
    ", (double)clock() / CLOCKS_PER_SEC);
        return 0;
    }
  • 相关阅读:
    c语言动态申请内存(malloc与calloc)
    二维数组的指针
    二分查找(用c语言实现)
    Docker一篇从入门到实战
    MyBatisPlus一篇从入门到实战
    MyBatis一篇从入门到实战
    MySQL一篇从入门到实战
    Nginx一篇从入门到实战
    day04_02逻辑运算符
    day4_01循环引用带来的内存泄露问题
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626459.html
Copyright © 2020-2023  润新知