23.8.8 杭电暑期多校7部分题解

这篇具有很好参考价值的文章主要介绍了23.8.8 杭电暑期多校7部分题解。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

1008 - H.HEX-A-GONE Trails

题目大意

有两个玩家和一棵树,初始状态玩家一和玩家二分别在两个点 x ,   y x,\space y x, y,每次操作可以走一个与当前点有连边并且双方都没走到过的点,问最后是谁赢

解题思路

因为不能走走过的点,因此每个人走的路径一定是一条链

很明显当玩家一不选择往与玩家二所在的点的路径走,相当于把 x → y x\to y xy 的链让给了玩家二

因此如果想要这么走就应该保证对方此时能走的链没有比你要走的长

那么可以开个数组存储 x → y x\to y xy 路径上每个点只经过非路径上的点所能走的最长的链长,可以用树形dp解决

这样操作之后就将问题转化到了数组中解决

双方分别用set维护在当前点所能到达的最远的距离

如果当前玩家离开 x → y x\to y xy 的路径能到的最远的距离比对方set内的最大值大则必胜

如没有必胜策略则继续沿路径走并在双方set中删除不可达的方案

如果双方到见面了还没必胜则比较两者接下来能到的最远距离

具体细节参考代码,哥们觉得太抽象了不好讲

code文章来源地址https://www.toymoban.com/news/detail-637353.html

#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9;
struct lol {int x, y;} e[N << 1];
int t, n, a, b, ans, top[N], vis[N], dep[2][N], f[2][N], p[N], fl;
multiset <int> s[2];
void ein(int x, int y) {
    e[++ ans].x = top[x];
    e[ans].y = y;
    top[x] = ans;
}
void dfs(int x, int fa, int op) {
    vis[x] ^= 1; f[op][x] = fa; dep[op][x] = dep[op][fa] + 1;
    if ((x == a || x == b) && fa != 0) return;
    for (int i = top[x]; i; i = e[i].x) {
        int y = e[i].y;
        if (y == fa) continue;
        dfs(y, x, op);
    }
}
void dfs1(int x, int fa, int rt) {
    p[rt] = max(p[rt], max(dep[0][x] - dep[0][rt], dep[1][x] - dep[1][rt]) + 1);
    for (int i = top[x]; i; i = e[i].x) {
        int y = e[i].y;
        if (vis[y] == 2 || y == fa) continue;
        dfs1(y, x, rt);
    }
}
int main() {
    scanf("%d", &t);
    while (t --) {
        scanf("%d%d%d", &n, &a, &b); ans = fl = 0;
        s[0].clear(); s[1].clear();
        for (int i = 1; i <= n; ++ i)
            top[i] = p[i] = vis[i] = dep[0][i] = dep[1][i] = 0;
        for (int i = 1, u, v; i < n; ++ i)
            scanf("%d%d", &u, &v), ein(u, v), ein(v, u);
        dfs(a, 0, 0);
        dfs(b, 0, 1);
        for (int x = b; x; x = f[0][x]) vis[x] = 2;
        for (int x = b; x; x = f[0][x]) {
            dfs1(x, 0, x);
            if (x != b) s[0].insert(p[x] + dep[0][x] - 1);
            if (x != a) s[1].insert(p[x] + dep[1][x] - 1);
        }
        int x1 = a, x2 = b, i;
        for (i = 0; x1 != f[0][x2]; ++ i)
            if ((i & 1) == 0) {
                if (p[x1] > *prev(s[1].end()) - i / 2) {fl = 1; break;}
                auto it = s[0].find(p[x1] + i / 2); s[0].erase(it);
                x1 = f[1][x1];
                it = s[1].find(p[x1] + dep[1][x1] - 1); s[1].erase(it);
            } else {
                if (p[x2] > *prev(s[0].end()) - (i + 1) / 2) {fl = 1; break;}
                auto it = s[1].find(p[x2] + i / 2); s[1].erase(it);
                x2 = f[0][x2];
                it = s[0].find(p[x2] + dep[0][x2] - 1); s[0].erase(it);
            }
        if (fl) printf("%d\n", (i & 1) ^ 1);
        else if ((i & 1) == 1) printf("%d\n", p[x2] > p[x1] ? 0 : 1);
        else printf("%d\n", p[x1] > p[x2] ? 1 : 0);
    }
    return 0;
}

到了这里,关于23.8.8 杭电暑期多校7部分题解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 2022杭电多校第一场B题Dragon slayer

    题目链接Problem - 7139 (hdu.edu.cn) 数据范围为15,直接枚举所有墙的方案,然后看是否能搜索到终点,如果可以就更新ans 需要注意的是如何处理:起点终点坐标+0.5造成的下标为小数,这里把所有坐标都乘2来避免double类型的出现 代码如下:

    2024年02月16日
    浏览(41)
  • (杭电多校)2023“钉耙编程”中国大学生算法设计超级联赛(4)

    1003 Simple Set Problem 双指针的思想,双端队列 先从小到大排个序 一个一个放到双端队列里,一边放一边维护集合个数为k个 利用滑动窗口,当滑动窗口中集合个数为k时,只需算出滑动窗口最后一个数减去第一个数,然后每次取min就行了 AC代码:  1006 PSO  两两组合 期望=所有组合的边

    2024年02月15日
    浏览(49)
  • 动态规划报告(树形DP+概率DP

    树形 DP,即在树上进行的 DP。由于树固有的递归性质,树形 DP 一般都是递归进行的。一般需要在遍历树的同时维护所需的信息 以一道题目为例 2022CCPC桂林站G Group Homework No, we don’t want group homework. It’s the place where 1+11 can be true. However, you are currently the leader of a group with three

    2024年02月12日
    浏览(46)
  • 树形DP()

    Ural 大学有 N 名职员,编号为 1∼N。 他们的关系就像一棵以校长为根的树,父节点就是子节点的直接上司。 每个职员有一个快乐指数,用整数 Hi 给出,其中 1≤i≤N。 现在要召开一场周年庆宴会,不过,没有职员愿意和直接上司一起参会。 在满足这个条件的前提下,主

    2024年02月09日
    浏览(30)
  • 动态规划之树形DP

    树形DP是指在“树”这种数据结构上进行的动态规划:给出一颗树,要求以最少的代价(或取得最大收益)完成给定的操作。通常这类问题规模比较大,枚举算法效率低,无法胜任,贪心算法不能求得最优解,因此需要用动态规划进行求解。 在树上做动态规划显得非常合适,

    2024年02月05日
    浏览(43)
  • 动态规划-树形DP

    链接:https://www.acwing.com/problem/content/848/ 给定一颗树,树中包含 n n n 个结点(编号 1 ∼ n 1 sim n 1 ∼ n )和 n − 1 n-1 n − 1 条无向边。 请你找到树的重心,并输出将重心删除后,剩余各个连通块中点数的最大值。 重心定义:重心是指树中的一个结点,如果将这个点删除后,剩

    2024年02月08日
    浏览(37)
  • 算法套路十九——树形DP

    树形 DP,即在树上进行的 DP。由于树固有的递归性质,这里的DP是指是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法,故虽然带有DP,但一般都是通过 递归 来进行。 给定一棵二叉树,你需要计算它的直径长度。一棵二叉树的直径长度是任意两个结点路

    2024年02月10日
    浏览(87)
  • 动态规划——树形DP 学习笔记

    前置知识:树基础。 树形 DP,即在树上进行的 DP,最常见的状态表示为 (f_{u,cdots}) ,表示以 (u) 为根的子树的某个东东。 本文将讲解一些经典题目(树的子树个数、树的最大独立集、树的最小点覆盖、树的最小支配集、树的直径、树的重心、树的中心),以及一些常见形

    2024年02月08日
    浏览(37)
  • [ACM学习] 树形dp之换根

    总的来说: 题目描述:一棵树求哪一个节点为根时,XXX最大或最小 分为两步:1. 树形dp  2. 第二次dfs 如果暴力就是 O(n^2) , 当从1到2的时候,2及其子树所有的深度都减一,其它的点,所有的深度都加一。写成递推方程如下: 思路是:第一遍 dfs 遍历的时候先把以某一确定点

    2024年01月24日
    浏览(28)
  • 动态规划树形DP课后习题蓝桥舞会

      蓝桥舞会 题目描述 蓝桥公司一共有n名员工,编号分别为1~n。 他们之间的关系就像一棵以董事长为根的树,父节点就是子节点的直接上司。每个员工有一个快乐指数aj。 现蓝桥董事会决定举办一场蓝桥舞会来让员工们在工作之余享受美好时光,不过对于每个员工,他们都

    2024年02月21日
    浏览(43)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包