zoukankan      html  css  js  c++  java
  • CXB 糖果

    题目描述

      你和朋友Shary玩一个游戏:在一个无环的、无向的图中,每个节点可以放一些糖果。每次Shary可以从糖果数不少于2的节点上拿2个糖果,吃掉1个,并把另一个糖果放到相邻的某个节点去。如果在某个时候,目标节点T上有了糖果,游戏结束,Shary赢。

      如果你设计的初始状态,无论如何Shary都赢不了,则Shary输。

      给定一个图,你能赢的方案中可以放的最多糖果数是多少?如果答案数超过2*10^9,只要输出-1即可。

    输入格式

      (多组数据形式)

      第1行:一个不超过5 的正整数K,表示有K组任务。

      下面有K组数据,每组数据格式为:

       第一行有2个正整数:N 和 T 。N表示节点数,节点编号从0到N-1,N不超过50;T是目标节点编号,范围在[0, N-1]。

       下面有N行,每行有N个字符,每个字符是”Y”或”N”。第i行第j个字符如果是”Y”就表示第i点和第j点有边相连,如果是”N”就表示第i点和第j点没有边相连。保证图上没有环。

    输出格式

      一个整数。

    输入样例

    3

    3 2

    NYN

    YNY

    NYN

    4 1

    NYYY

    YNNN

    YNNN

    YNNN

    7 0

    NYNNNYN

    YNYNYNN

    NYNYNNN

    NNYNNNN

    NYNNNNN

    YNNNNNY

    NNNNNYN

    输出样例

    3

    4

    11

    题解

      我们可以把题目中的图看作一棵树,则$t$为根节点。

      容易想到,如果要让$t$为$0$,则这个点的出点(深度为$2$)的点最多为$1$,出点的出点(深度为$3$)最多为$3$,出点的出点的出点(深度为$4$)最多为$7$......深度为$n$的点最多为$2n-1$。

      而一组出点中,如果有一个点为$2n-1$,则其他点都为$1$。

      根据贪心的得,我们要把$2n-1$继承给当前点为根节点的子树的长链。暴力dfs即可。

      注意判断$t$是否能到达任意点,如果不能,则初始状态可以放正无穷个糖果。

    #include <iostream>
    #include <cstring>
    
    #define MAX_N (50 + 5)
    
    using namespace std;
    
    struct Edge
    {
        int to;
        int next;
    };
    
    const long long lim = 2000000000LL;
    int T;
    int n, root;
    char l[MAX_N][MAX_N];
    int h[MAX_N];
    Edge e[MAX_N];
    int cnt;
    int dep[MAX_N];
    long long ans;
    
    void Init()
    {
        memset(h, 0, sizeof h);
        memset(e, 0, sizeof e);
        memset(dep, 0, sizeof dep);
        cnt = ans = 0;
        return;
    }
    
    inline void Make_Edge(int u, int v)
    {
        e[++cnt].to = v;
        e[cnt].next = h[u];
        h[u] = cnt;
        return;
    }
    
    void Build(int u, int p)
    {
        for(register int v = 1; v <= n; ++v)
        {
            if(l[u][v] != 'Y' || v == p) continue;
            Make_Edge(u, v);
            Build(v, u);
            dep[u] = max(dep[u], dep[v]);
        }
        ++dep[u];
        return;
    }
    
    void DFS(int u, long long val)
    {
        int v, p = 0;
        for(register int i = h[u]; i; i = e[i].next)
        {
            v = e[i].to;
            if(dep[p] < dep[v]) p = v;
        }
        if(!p)
        {
            ans += val;
            return;
        }
        DFS(p, val << 1 | 1LL);
        for(register int i = h[u]; i; i = e[i].next)
        {
            v = e[i].to;
            if(p != v) DFS(v, 1LL);
        }
        return;
    }
    
    int main()
    {
        cin >> T;
        while(T--) 
        {
            Init();
            cin >> n >> root;
            ++root;
            for(register int i = 1; i <= n; ++i)
            {
                cin >> l[i] + 1;
            }
            Build(root, -1);
            bool op = false;
            for(register int i = 1; i <= n; ++i)
            {
                if(!dep[i]) 
                {
                    printf("-1
    ");
                    op = true;
                    break;
                }
            }
            if(op) continue;
            DFS(root, 0);
            if(ans > lim) cout << "-1
    ";
            else cout << ans << "
    ";
        }
        return 0;
    }
    参考程序
  • 相关阅读:
    SQLserver1数据库操作
    系统信息相关命令的学习
    打包压缩(tar指令)
    用户管理相关内容的学习(chmod修改文件权限(附加)及实例)
    用户管理相关内容的学习(查看文件权限 修改文件权限chmod 改变文件归属chown和chgrp)
    用户管理相关内容的学习(su切换用户)
    用户管理相关内容的学习(which命令的使用 查看命令所在的位置)
    用户管理相关内容的学习(登录xshell)
    用户管理相关内容的学习(设置主组和附加组)
    用户管理相关内容的学习查看用户信息(who whoami)
  • 原文地址:https://www.cnblogs.com/kcn999/p/10806660.html
Copyright © 2011-2022 走看看