zoukankan      html  css  js  c++  java
  • 2020杭电第九场

    1001. tree

    1001. tree

    题意

    一棵根为1的树,要求选择两个节点加一条单向边,使得的二元组数量最多

    思路

    从一个点出发可以到达他的所有子节点和他自己,添加一条边使得(x,y)(从x到y)最多,添加的这条边的终点最好的情况就是连一个子节点最多的点,也就是直接连到根节点1是最优的情况

    第一次搜索,用来记录未加边时

    用dept记录深度,dp记录元组数,sum记录元组和

    第二次搜索,用来记录加边后重复元组的数量

    n * dept - tt 为增量

    代码

    /*************************************************************************
     > FileName:
     > Author:      Lance
     > Mail:        lancelot_hcs@qq.com
     > Date:        9102.1.8
     > Description:
     ************************************************************************/
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const double pi = acos(-1.0);
    const double eps = 1e-6;
    const int mod = 1e9 + 7;
    #define debug(a) cout << "*" << a << "*" << endl
    const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
    const int maxn = 500005;
    //sacnf("%lf") printf("%f")
    ll read()
    {
        ll x = 0,f = 1;
        char ch = getchar();
        while (ch < '0' || ch > '9')
        {
            if (ch == '-')
            f = -1;
            ch = getchar();
        }
        while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
        return x * f;
    }
    ll t, n;
    vector<ll> G[maxn];
    
    ll dp[maxn];
    ll dept[maxn];
    ll tt[maxn], sum = 0;
    void dfs(int x, int fa) {
        if (x == 1) dept[x] = 1;
        else dept[x] = dept[fa] + 1;
        dp[x] = 1;
        for (int i = 0; i < G[x].size(); i++) {
            int tem = G[x][i];
            if (tem != fa) {
                dfs(tem, x);
                dp[x] += dp[tem];
            }
        }
        sum += dp[x]; 
    }
    
    void dfs1(int x, int fa) {
        tt[x] = tt[fa] + dp[x];
        for (int i = 0; i < G[x].size(); i++) {
            int tem = G[x][i];
            if (tem != fa) {
                dfs1(tem, x);
            }
        }
    }
    
    
    void solve()
    {
        t = read();
        while (t--) {
            sum = 0;
            n = read();
            int a;
            for (int i = 2; i <= n; i++) {
                a = read();
                G[a].push_back(i);
            }
            dfs(1, 0);
            dfs1(1, 0);
            ll max_ = -INF, index = 0;
            for (int i = 1; i <= n; i++) {
                max_ = max(max_, n * dept[i] - tt[i]);
            }
            printf("%lld
    ", sum + max_);
            for (int i = 1; i <= n; i++) {
                G[i].clear();
                dp[i] = 0;
                dept[i] = 0;
                tt[i] = 0;
            }
        }
    }
    
    int main()
    {
    
    //    freopen("F:/Overflow/in.txt","r",stdin);
    //    ios::sync_with_stdio(false);
        solve();
        return 0;
    }
    

    1003. Slime and Stones

    1003.Slime and Stones

    题意

    威尔逊博弈的拓展, 威佐夫博弈是本题的k = 0 的情况

    思路

    待续

    代码

    ///*************************************************************************
    // > FileName:
    // > Author:      Lance
    // > Mail:        lancelot_hcs@qq.com
    // > Date:        9102.1.8
    // > Description:
    // ************************************************************************/
    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> PII;
    const double pi = acos(-1.0);
    const double eps = 1e-6;
    const int mod = 1e9 + 7;
    #define debug(a) cout << "*" << a << "*" << endl
    const int INF = 0x3f3f3f3f;//int2147483647//ll9e18//unsigned ll 1e19
    const int maxn = 1000005;
    //sacnf("%lf") printf("%f")
    ll read()
    {
       ll x = 0,f = 1;
       char ch = getchar();
       while (ch < '0' || ch > '9')
        {
            if (ch == '-')
            f = -1;
            ch = getchar();
        }
       while (ch >= '0' && ch <= '9')
        {
            x = x * 10 + ch - '0';
            ch = getchar();
        }
       return x * f;
    }
    ll t, n, a, b, k;
    
    void solve()
    {
        t =read();
        while (t--) {
            a = read(), b = read(), k = read();
            if (a > b) {
                swap(a, b);
            }
            k++;
            n = b - a;
            if (n % k) {
                puts("1");
                continue;
            } else {
                if (int(n * ((2 - k) * 1ll + sqrt(k * k * 1.0 + 4.0)) / 2 / k) == a) {
                    puts("0");
                } else {
                    puts("1");
                }
            }
            
        }
    }
    
    int main()
    {
    
    //    freopen("F:/Overflow/in.txt","r",stdin);
    //    ios::sync_with_stdio(false);
       solve();
       return 0;
    }
    

    参考博客

    https://www.cnblogs.com/stelayuri/p/13525300.html

  • 相关阅读:
    NOJ-1581 筷子 (线性DP)
    UVA-242 Stamps and Envelope Size (DP)
    POJ 1860 (SPFA判断正环)
    POJ 3268 最短路水题
    STL----priority_queue
    STL----unique
    POJ 2031(最小生成树Kruskal算法+几何判断)
    POJ 3468(线段树区间修改+区间求和)
    学习线段树
    POJ 1251(最小生成树裸题)
  • 原文地址:https://www.cnblogs.com/lanclot-/p/13532543.html
Copyright © 2011-2022 走看看