思路:我以前一直喜欢用根号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<map>
#include<set>
#include<cmath>
#include<queue>
#include<cstdio>
#include<vector>
#include<string>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#define Maxn 100010
#define Maxm 200010
#define LL __int64
#define Abs(x) ((x)>0?(x):(-x))
#define lson(x) (x<<1)
#define rson(x) (x<<1|1)
#define inf 0x7fffffff
#define Mod 1000000007
using namespace std;
int head[Maxn],vi[Maxn],val[Maxn],e,dp[Maxn],fs[Maxn],fa[Maxn],out[Maxn],cnt[Maxn],anc[Maxn],vis[Maxn],n,m;
struct Edge{
int u,v,next;
}edge[Maxm];
vector<int> ll[Maxn];
void init()
{
memset(head,-,sizeof(head));
memset(vi,,sizeof(vi));
memset(out,,sizeof(out));
memset(cnt,,sizeof(cnt));
memset(fs,,sizeof(fs));
e=;
}
void add(int u,int v)
{
edge[e].u=u,edge[e].v=v,edge[e].next=head[u],head[u]=e++;
edge[e].u=v,edge[e].v=u,edge[e].next=head[v],head[v]=e++;
}
void Treedp(int u)
{
int i,v;
vi[u]=;
dp[u]=;
for(i=head[u];i!=-;i=edge[i].next){
v=edge[i].v;
if(vi[v]) continue;
Treedp(v);
dp[u]+=dp[v];
if(!out[v]) dp[u]+=m;
else if(out[v]==) dp[u]++;
out[u]+=out[v];
}
out[u]-=cnt[u];
}
int find(int x)
{
if(x!=fa[x])
fa[x]=find(fa[x]);
return fa[x];
}
void merg(int a,int b)
{
int x=find(a);
int y=find(b);
if(fs[y]<=fs[x])
fa[y]=x,fs[x]+=fs[y];
else fa[x]=y,fs[y]+=fs[x];
}
void LCA(int u)
{
int i,v,sz;
sz=ll[u].size();
vi[u]=;
anc[u]=u;
for(i=head[u];i!=-;i=edge[i].next){
v=edge[i].v;
if(vi[v]) continue;
LCA(v);
merg(u,v);
anc[find(u)]=u;
}
vis[u]=;
for(i=;i<sz;i++){
v=ll[u][i];
if(vis[v]){ int lca=anc[find(v)];
if(lca==u){
out[v]++;
cnt[u]++;
}else if(lca==v){
out[u]++;
cnt[v]++;
} else {
cnt[lca]+=;
out[u]++,out[v]++;
}
}
}
}
int main()
{
int i,j,u,v;
scanf("%d%d",&n,&m);
memset(head,-,sizeof(head));
for(i=;i<Maxn;i++)
fa[i]=i,fs[i]=;
for(i=;i<n;i++){
scanf("%d%d",&u,&v);
add(u,v);
}
for(i=;i<=m;i++){
scanf("%d%d",&u,&v);
ll[u].push_back(v);
ll[v].push_back(u);
}
LCA();
memset(vi,,sizeof(vi));
Treedp();
printf("%d\n",dp[]);
return ;
}

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

  1. Fire (poj 2152 树形dp)

    Fire (poj 2152 树形dp) 给定一棵n个结点的树(1<n<=1000).现在要选择某些点,使得整棵树都被覆盖到.当选择第i个点的时候,可以覆盖和它距离在d[i]之内的结点,同 ...

  2. poj 3417 Network(tarjan lca)

    poj 3417 Network(tarjan lca) 先给出一棵无根树,然后下面再给出m条边,把这m条边连上,然后每次你能毁掉两条边,规定一条是树边,一条是新边,问有多少种方案能使树断裂. 我们设 ...

  3. poj 1463(树形dp)

    题目链接:http://poj.org/problem?id=1463 思路:简单树形dp,如果不选父亲节点,则他的所有的儿子节点都必须选,如果选择了父亲节点,则儿子节点可选,可不选,取较小者. #i ...

  4. poj 2486( 树形dp)

    题目链接:http://poj.org/problem?id=2486 思路:经典的树形dp,想了好久的状态转移.dp[i][j][0]表示从i出发走了j步最后没有回到i,dp[i][j][1]表示从 ...

  5. poj 3140(树形dp)

    题目链接:http://poj.org/problem?id=3140 思路:简单树形dp题,dp[u]表示以u为根的子树的人数和. #include<iostream> #include ...

  6. poj3417 Network 树形Dp+LCA

    题意:给定一棵n个节点的树,然后在给定m条边,去掉m条边中的一条和原树中的一条边,使得树至少分为两部分,问有多少种方案. 神题,一点也想不到做法, 首先要分析出加入一条边之后会形成环,形成环的话,如果 ...

  7. hdu_5293_Tree chain problem(DFS序+树形DP+LCA)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293 被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写 ...

  8. Strategic game(POJ 1463 树形DP)

    Strategic game Time Limit: 2000MS   Memory Limit: 10000K Total Submissions: 7490   Accepted: 3483 De ...

  9. POJ 2342 树形DP入门题

    有一个大学的庆典晚会,想邀请一些在大学任职的人来參加,每一个人有自己的搞笑值,可是如今遇到一个问题就是假设两个人之间有直接的上下级关系,那么他们中仅仅能有一个来參加,求请来一部分人之后,搞笑值的最大是 ...

随机推荐

  1. 【转】google推出的SwipeRefreshLayout下拉刷新用法

    SwipeRefreshLayout是Google在support v4 19.1版本的library更新的一个下拉刷新组件,实现刷新效果更方便. 使用如下: 1.先下载android-support ...

  2. ORA-04091: 表 发生了变化, 触发器/函数不能读它

    触发器中新调用了一个存储过程. 触发器: create or replace trigger tr_credits_wzclorder_clwzjk after update on app_wzclo ...

  3. php中curl不支持https的解决办法

    在php程序中使用curl去访问https站点时,报错:Protocol https not supported or disabled in libcurl 该错误信息表示php当时编译时使用的cu ...

  4. 深入理解DLL文件

    1.LIB与DLL文件的区别 DLL是一个完整的程序,称为“动态链接库”,DLL中包含的主要有三块内容:1.全部变量 2.函数接口 3.资源:DLL中有一个函数导出表,其中每一项都是一个函数名称.通过 ...

  5. CSS实现标题右侧“更多”

    HTML < h2>< a h ref="#" >标题< /a> < span>更多…< /span> < /h2 ...

  6. pad 横屏 cell不正常显示

    在iOS9中,适配iPad横屏的时候,我发现cell不能正常显示,其标题和线都不是从左边头部开始,而是在中间,accessoryType的图标也不再右边尾部,效果如下图 但是在iPhone中是正常的, ...

  7. vs2013 设置为中文版

  8. 推荐安卓开发神器(里面有各种UI特效和实例)

    网上有很多开源的安卓类库很好用,对于刚学习安卓的童鞋亦或者老鸟都是很好的学习对象. 我平时有关注开源代码的习惯,这么多年也搜集了不少精彩的源码. 到后来发现自己手机里装的都是几百个demo app,删 ...

  9. AutoCAD按坐标打印图纸

    前几天公司要求按坐标打印DWG文件,中间走了不少弯路,好在已经搞定了,整理一下分享给大家,希望后来人少走弯路. 1. 设计需求: 公司的图纸用AutoCAD2010做成,通常一个项目的所有图纸都存放在 ...

  10. [Angular2 Router] Configuring a Home Route and Fallback Route - Learn An Essential Routing Concept

    In this tutorial we are going to learn how to configure the Angular 2 router to cover some commonly ...