poj 3417 树形dp+LCA】的更多相关文章

思路:我以前一直喜欢用根号n分段的LCA.在这题上挂了,第一次发现这样的LCA被卡.果断改用Tarjan离线算法求LCA. 当前节点为u,其子节点为v.那么: 当以v根的子树中含有连接子树以外点的边数为out[v]. out[v]==0,dp[u]+=m; out[v]==1,dp[u]+=1; else dp[u]+=0; 最后就是dp[u]+=dp[v]. 对于u点的out[u]+=out[v]; 最后out[u]-=cnt[u]:cnt[u]表示以u为根,在子树内的边数. #include…
Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同时花费为v[i].问最小花费. 以前做过一道类似的题(水库),这道题也差不多.首先来考虑,用\(best[i]\)表示以i为根的子树的最小花费.这样做有什么问题呢?它无法很好的处理消防站重复建的问题. 所以换一种做法.\(best[i]\)依然表示原来的含义,新建一个数组\(f[i][j]\),表示当i这个结…
poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设添加了一条新边后,树形成了一个环,表示为x->y->lca(x,y),我们将其中的边都覆盖一次.添加了多条新边后,可知树上有些边是会被多次覆盖的,画图很容易发现,但一个树边被覆盖了2次或以上,它就是一条牢固的边,就是说毁掉它再毁掉任何一条新边都好,树都不会断裂.所以我们只要统计被覆盖过零次或一次的…
题目链接:http://poj.org/problem?id=1463 思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define MAXN 22…
题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从i出发走了j步最后回到i.于是我们把所有到情况归结为3种: 1.从u(v是其中一颗子树)出发,走了j步,最后停在了v,则有dp[u][j+1][0]=max(dp[u][j+1][0],dp[u][j-k][1]+dp[v][k][0]);(从u->v多走了1步). 2.从u出发,走了j步,最后停在…
题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<climits> #include<algorithm> #include<stack>…
题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果去掉该边和环上面没有被其他环覆盖的边,那么便分为两部分了. 这样只需要记录每条边被环覆盖了几次即可, 用dp[u]表示u点的父边被覆盖了几次. 每次新加进来一条边(a,b) dp[a] ++ ,dp[b] ++ , dp[lca(a,b)] -= 2; 所有边处理完之后,遍历一边此树,同时转移状态…
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写树剖,不过这里DFS序更简单,因为都是对点到根的操作 #include<cstdio> #include<vector> #include<algorithm> #pragma comment(linker, "/STACK:102400000,102400000…
Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 7490   Accepted: 3483 Description Bob enjoys playing computer games, especially strategic games, but sometimes he cannot find the solution fast enough and then he is very sad…
有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是多少. 树形DP入门题. DP部分: dp[i][0]表示职员i不来參加party,以i为根的子树的最大搞笑值, dp[i][1]表示职员i来參加party.以i为根的子树的最大搞笑值. 转移方程: dp[cur][1]+=dp[next][0]; dp[cur][0]+=Max(dp[next][…
题目连接:http://acm.hust.edu.cn/vjudge/problem/17665 参考资料:http://blog.csdn.net/woshi250hua/article/details/7684771 题目大意:xx大佬要竞选xx职位,现一共有n个国家,获得xx职位至少需要m个国家的支持,某个国家下面会有若干个附属国家,这个代表获得这个国家的支持就可以获得一群国家的支持.想要获得这个国家的支持,就必须拿钻石去贿赂,好厚黑.问获得xx职位最少需要多少钻石. 这道题有几个要点:…
题意:电视台发送信号给很多用户,每个用户有愿意出的钱,电视台经过的路线都有一定费用,求电视台不损失的情况下最多给多少用户发送信号. 转自:http://www.cnblogs.com/andre0506/archive/2012/10/09/2717441.html 思路: 基础树形DP. x表示当前在的节点.j表示选j个收听电视. f[x][j]=max(f[x][j],f[x.son][k]+f[x][j-k]-w[i]); // by SiriusRen #include <cstdio>…
这是很久很久以前做的一道题,可惜当时WA了一页以后放弃了. 今天我又重新捡了起来.(哈哈1A了) 题意: 没有上司的舞会+判重 思路: hash一下+树形DP 题目中给的人名hash到数字,再进行运算. 树形DP f[x][0]+=max(f[x.son][0],f[x.son][1]); f[x][1]+=f[x.son][0]; f[x][0]表示不选这个节点,f[x][1]表示选这个节点. 如果选了这个节点,那么它的儿子必定不选. 如果不选这个节点,它的儿子们可选可不选 取最大的即可. 然…
咋一看确实想到的是树形DP,但是我一开始也马上想到环的情况,这样应该是不可以进行树形DP的,然后我自以为是地想用有向图代替无向图,而且总是从能量高的指向能量低的,这样自以为消除了环,但是其实是不对滴,这样的话在树形DP的过程中就会出问题.然后实在没想到好的方法,去看 了下这题的discuss,结果大家都说数据不会有环,为什么呢,因为题目的隐含条件就是从一个状态到另一个状态有且只有一条路径,我又仔细看了下题目,找是找到了类似的话,说只能遵循这样的变化,但是不知道是我的认知跟别人不一样还是怎么回事,…
题意: N个点,构成一棵树.给出这棵树的结构. M条边,(a1,b1)...(am,bm),代表给树的这些点对连上边.这样就形成了有很多环的一个新"树". 现在要求你在原树中断一条边,在M条边中断一条边,使得新"树"被分成两个部分. 问有多少种方案. 思路: 连上某条新边(a,b),则必定形成一个环.环的路径是a->...->lca(a,b)->...->b,给这些边的值都加1 . 分情况: 在原树中,若一条边的值>=2,去掉这条边,再…
题目:https://vjudge.net/contest/323605#problem/E 题意:一棵n个点的树,然后有m个查询,每次查询找(u->v)路径上的两个数,a[i],a[j],(i<j)a[j]-a[i]的最大值,j必须是u->v路径上出现的比i晚 思路:首先我们路径肯定是确定只有一条的,然后我们怎么找出那条路径呢,我们可以求LCA,求出u->LCA(u,v)   LCA(u,v)->v  ,这样我们就能把路径给确定出来 然后我们先简化问题,如果是一个序列,我们…
题目链接: http://poj.org/problem?id=1155 题目大意:电视台转播节目.对于每个根,其子结点可能是用户,也可能是中转站.但是用户肯定是叶子结点.传到中转站或是用户都要花钱,如果是用户,则还可以收钱.问在不亏本的前提下最多能有多少个用户看到节目. 解题思路: 比较麻烦的树形背包.首先cost=1. 花的钱权在边,收的钱权在点,且是叶子结点.所以首先可以对叶子结点进行预处理. 用dp[i][j]表示在i点时传播j个用户(包含自身),则dp[n-m-1~n][1]=每个用户…
题目链接: http://poj.org/problem?id=2342 题目大意:直属上司和下属出席聚会.下属的上司出现了,下属就不能参加,反之下属参加.注意上司只是指直属的上司.每个人出席的人都有一个快乐值,问最大的快乐值是多少. 解题思路: 首先确定一下顶头上司是谁. f[v]=u表示u是v的父亲,这样addedge完了之后,从1开始while(f[root]) root=f[root],最后root就是顶头上司,也就是dfs的起点了. 用dp[i][0]表示对于第i个人不出席的最大快乐值…
http://poj.org/problem?id=2342 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<queue> #include<vector> using namespace std; inline int read(){ ,x=; char ch=getchar(); '){ if(ch=='-') x…
题目链接:http://poj.org/problem?id=2378 思路:num[u]表示以u为根的子树的顶点个数(包括),如果去掉u之后u的每棵子树都小于等于n/2,则选择u. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<vector> using namespace std; #define MAXN 11111 #d…
题目链接:http://poj.org/problem?id=1935 思路:首先我们考虑从源点出发到所有自己想要经过的点然后在回到源点sum,显然每条边都必须经过源点(这个我们可以一次dfs求出),但题目的意思是可以不用回到源点,那么我们可以再求源点到所有要经过的点的最远距离ans,于是答案便是sum-ans. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm>…
思路:这个没思路,看了陈启峰的论文写得. #include<map> #include<set> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<iomanip> #include<cstdlib> #include<cstring> #include&…
思路: 每个点有三种状态,本身有塔,被子节点的塔覆盖,被父节点的塔覆盖. #include<map> #include<set> #include<cmath> #include<queue> #include<cstdio> #include<vector> #include<string> #include<cstdlib> #include<cstring> #include<iostr…
思路:dp[i][j]表示,以i节点为根,删去j个节点最少要断几条边. 那么dp[u][j]=min(dp[u][j],dp[v][k]+dp[u][j-k]);//选取最优状态 dp[u][j]=min(dp[u][j],dp[u][j-son[v]]+1);//切断与子节点相连的边 对于子节点 dp[v][n-son[v]]=1; dp[v][j]=min(dp[v][j],dp[v][j-n+son[v]]+1)//表示不需要由父节点过来的那条分支 最有从所有状态中选举最优的dp[i][n…
思路:表示我很弱,这个想不出dp方程,参考网上代码 #include<iostream> #include<algorithm> #include<cstring> #include<cstdio> #include<algorithm> #include<vector> #define inf 1<<20 #define Maxn 110 using namespace std; ],vi[Maxn]; vector&l…
先选一点为根节点找出所有父节点i到下面所有点距离和dp[i],该父节点下面有多少个点Node[i]. 然后求出所有节点的所有非子节点到该点的距离dp1[v]+=(dp1[u]+(dp[u]-dp[v]-Node[v]-1)+n-Node[v]-1) dp[u]-dp[v]-Node[v]-1:u的子节点中除了v这一部分子节点到u的距离 n-Node[v]-1:非v的字节点的个数 #include<stdio.h> #include<string.h> #define N 50002…
Anniversary party Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 5767   Accepted: 3335 Description There is going to be a party to celebrate the 80-th Anniversary of the Ural State University. The University has a hierarchical structure…
POJ1463是一个典型的树状DP题. 通常解法如下代码所示: using namespace std; ; ]; int pre[maxn]; int childcnt[maxn]; int n; void dp(int cur){ ]>=||d[cur][]>=){ return; } ){ d[cur][]=;d[cur][]=; return ; } ;i<n;i++){ if(pre[i]==cur){ dp(i); ]==-)d[cur][]=; ]==-)d[cur][]=…
Rebuilding Roads Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10663   Accepted: 4891 Description The cows have reconstructed Farmer John's farm, with its N barns (1 <= N <= 150, number 1..N) after the terrible earthquake last May. Th…
最优连通子集 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 2589   Accepted: 1382 Description 众所周知,我们可以通过直角坐标系把平面上的任何一个点P用一个有序数对(x, y)来唯一表示,如果x, y都是整数,我们就把点P称为整点,否则点P称为非整点.我们把平面上所有整点构成的集合记为W. 定义1 两个整点P1(x1, y1), P2(x2, y2),若|x1-x2| + |y1-y2|…