HDU - 2545 树上战争(并查集的思想转化题意)

题目链接https://vjudge.net/contest/323985#problem/L
给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxh和pfz初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜
Input
输入包含多组数据
每组第一行包含两个数N,M(N,M<=100000),N表示树的节点数,M表示询问数,N=M=0表示输入结束。节点的编号为1到N。
接下来N-1行,每行2个整数A,B(1<=A,B<=N),表示编号为A的节点是编号为B的节点的父亲
接下来M行,每行有2个数,表示lxh和pfz的初始位置的编号X,Y(1<=X,Y<=N,X!=Y),lxh总是先移动
Output
对于每次询问,输出一行,输出获胜者的名字

分析
对于树这种数据结构,如下图:2号节点是上一层(1)的子节点,又是下一层(4,5)的根节点。对于一棵树只有一个根节点,对应的,也只有根节点有f[u]=u;给出两个点的初始位置,可以通过比较点到根节点的距离,来判断输赢。
在这里插入图片描述
注意的是(sum初始化为1):再找祖先的时候,不进行路径压缩,从当前位置一直到根节点f[u]=u才结束while循环

int getf(int u,int sum)
{
    while(u!=f[u])/*直至到根节点*/
    {
        sum++;
        u=f[u];
    }
    return sum;
}

代码

#include<cstdio>/*谁离跟节点近,谁能赢*/
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 100001
int n,m,f[N];
void init()
{
    for(int i=1; i<=n; i++)
        f[i]=i;
}
int getf(int u,int sum)
{
    while(u!=f[u])/*直至到根节点*/
    {
        sum++;
        u=f[u];
    }
    return sum;
}
int main()
{
    while(~scanf("%d%d",&n,&m)&&(n+m))/*n为节点数,m为询问数*/
    {
        init();
        int vis=n-1;
        while(vis--)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            f[b]=a;
        }
        while(m--)
        {
            int t1,t2;
            scanf("%d%d",&t1,&t2);
            if(getf(t1,1)<=getf(t2,1))
                printf("lxh\n");
            else
                printf("pfz\n");
        }
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zaiyang遇见

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值