cdoj32-树上战争(Battle on the tree) 【记忆化搜索】

http://acm.uestc.edu.cn/#/problem/show/32

树上战争(Battle on the tree)

Time Limit: 12000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)

Submit Status

给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxhpfz初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜。

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个数,表示lxhpfz的初始位置的编号X,Y(1≤X,Y≤N,X≠Y),lxh总是先移动。

Output

对于每次询问,输出一行,输出获胜者的名字。

Sample input and output

Sample Input Sample Output
2 1
1 2
1 2
5 2
1 2
1 3
3 4
3 5
4 2
4 5
0 0
lxh
pfz
lxh

题解:记忆化搜索。这道题目,其实是要你求出两人所在节点的深度(即到根的距离),做个比较即可。实现时,把儿子指向父亲作为有向边,因为是树,所以n-1个节点对应n-1条有向边。做个记忆化搜索即可。

代码:

 1 #include <fstream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <iostream>
 5
 6 using namespace std;
 7
 8 const int N=100005;
 9 int n,m;
10 int u[N];
11 int dis[N];
12 bool b[N];
13
14 int dfs(int i);
15
16 int main()
17 {
18     //freopen("D:\\input.in","r",stdin);
19     //freopen("D:\\output.out","w",stdout);
20     int t1,t2;
21     while(scanf("%d%d",&n,&m),n){
22         memset(dis,-1,sizeof(dis));
23         memset(b,0,sizeof(b));
24         for(int i=1;i<n;i++){
25             scanf("%d%d",&t1,&t2);
26             u[t2]=t1;//由儿子指向父亲
27             b[t2]=1;
28         }
29         for(int i=0;i<m;i++){
30             scanf("%d%d",&t1,&t2);
31             if(dis[t1]==-1)   dfs(t1);
32             if(dis[t2]==-1)   dfs(t2);
33             if(dis[t1]<=dis[t2])    puts("lxh");
34             else    puts("pfz");
35         }
36     }
37     return 0;
38 }
39 int dfs(int i){
40     if(dis[i]!=-1)  return dis[i];
41     if(b[i]==0) return 0;
42     dis[i]=dfs(u[i])+1;
43     return dis[i];
44 }
时间: 2024-11-03 03:25:00

cdoj32-树上战争(Battle on the tree) 【记忆化搜索】的相关文章

UESTC 树上战争(Battle on the tree) Label:并查集?

给一棵树,如果树上的某个节点被某个人占据,则它的所有儿子都被占据,lxh和pfz初始时分别站在两个节点上,谁当前所在的点被另一个人占据,他就输了比赛,问谁能获胜. Input 输入包含多组数据 每组第一行包含两个数NN,MM(NN,M≤100000M≤100000),NN表示树的节点数,MM表示询问数,N=M=0N=M=0表示输入结束.节点的编号为11到NN. 接下来N−1N−1行,每行22个整数AA,BB(1≤A1≤A,B≤NB≤N),表示编号为AA的节点是编号为BB的节点的父亲. 接下来MM

CDOJ 32 树上战争(Battle on the tree) 解题报告

啊啊,最后一篇了,已经零点多了,我还打算写一段第一次打工赚钱做家教的感想呢…… 接下来有时间做决赛题,感觉也不是很难吼? 题目链接:http://acm.uestc.edu.cn/#/problem/show/32 很简单的题目,比较一棵有根树两个节点哪个高度. 同样,用了一行广搜.不要问我为什么叫一行广搜,不要让我压代码压得不成样子,编程可是一种艺术…… 也许我应该规范一下比如const变量的命名? #include <cstdio> #include <cstring> usi

【DP】树形DP 记忆化搜索

DP中的树形DP,解决方法往往是记忆化搜索.显然,树上递推是很困难的.当然做得时候还是得把状态定义和转移方程写出来:dp[u][1/0]表示以u为根节点的树 涂(1) 或 不涂(0) 颜色的最少方案数.树上DP有两个经典问法:一条边两端至少有个一个端点涂色,问整个tree最少涂色次数:还有一种忘了...此题是前种问法. #include<cstdio> #include<cstring> #include<algorithm> using namespace std;

uva11008 - Antimatter Ray Clearcutting(二进制+记忆化搜索)

题目:uva11008 - Antimatter Ray Clearcutting(二进制+记忆化搜索) 题目大意:给出n棵树的坐标,每次砍树能够将在同一直线上的树一起砍掉,然后给出要求你至少砍掉的树的数量,问你要达到这个要求需要砍多少次. 解题思路:因为这题的树的数量比较小(16), 并且只有砍和不砍两种选择,可以用二进制数将状态表示出来.大致思路是:每次都将当前状态下的还没砍的树中选择两棵,在将和这两个树在同一直线上的树一起砍掉,得到新的状态.如果已经>=K棵了,就可以返回0了.一般来说,每

hdu 1501 Zipper (dfs+记忆化搜索)

Zipper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 6491    Accepted Submission(s): 2341 Problem Description Given three strings, you are to determine whether the third string can be formed

BNU 20860——Forwarding Emails——————【强连通图缩点+记忆化搜索】

Forwarding Emails Time Limit: 1000ms Memory Limit: 131072KB This problem will be judged on UVA. Original ID: 1244264-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None Graph Theory 2-SAT

Codeforces 509F Progress Monitoring (区间dp 或 记忆化搜索)

F. Progress Monitoring time limit per test 1 second memory limit per test 256 megabytes Programming teacher Dmitry Olegovich is going to propose the following task for one of his tests for students: You are given a tree T with n vertices, specified b

HDU 1513 Palindrome:LCS(最长公共子序列)or 记忆化搜索

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513 题意: 给你一个字符串s,你可以在s中的任意位置添加任意字符,问你将s变成一个回文串最少需要添加字符的个数. 题解1(LCS): 很神奇的做法. 先求s和s的反串的LCS,也就是原串中已经满足回文性质的字符个数. 然后要变成回文串的话,只需要为剩下的每个落单的字符,相应地插入一个和它相同的字符即可. 所以答案是:s.size()-LCS(s,rev(s)) 另外,求LCS时只会用到lcs[i-

uva 1076 - Password Suspects(AC自动机+记忆化搜索)

题目链接:uva 1076 - Password Suspects 题目大意:有一个长度为n的密码,存在m个子串,问说有多少种字符串满足,如果满足个数不大于42,按照字典序输出. 解题思路:根据子串构建AC自动机,然后记忆化搜索,dp[i][u][s]表示第i个字符,在u节点,匹配s个子串. #include <cstdio> #include <cstring> #include <queue> #include <string> #include <