zoukankan      html  css  js  c++  java
  • hdu_5293_Tree chain problem(DFS序+树形DP+LCA)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5293

    被这题打蹦了,看着题解写的,很是爆炸,确实想不到,我用的DFS序+LCA+树形DP,当然也可以写树剖,不过这里DFS序更简单,因为都是对点到根的操作

     1 #include<cstdio>
     2 #include<vector>
     3 #include<algorithm>
     4 #pragma comment(linker, "/STACK:102400000,102400000")
     5 #define F(i,a,b) for(int i=a;i<=b;i++)
     6 #define root 1,n,1
     7 #define ls l,m,rt<<1
     8 #define rs m+1,r,rt<<1|1
     9 using namespace std;
    10 
    11 const int N=1e5+7,DEG=20;
    12 int t,n,m,x,y,dp[N],sum[N],c1[N*2],c2[N*2];
    13 struct edge{int u,v,w,lca;}p[N];
    14 vector<int>vec[N];
    15 inline void add(int x,int k,int *c){for(;x<=n*2;x+=x&-x)c[x]+=k;}
    16 inline int ask(int x,int *c){int an=0;while(x)an+=c[x],x-=x&-x;return an;}
    17 //LCA+dfs序
    18 int ed,g[N],nxt[2*N],v[2*N],fa[N][DEG],dep[N],idx,l[2*N],r[2*N];
    19 inline void adg(int x,int y){v[++ed]=y,nxt[ed]=g[x],g[x]=ed;}
    20 
    21 void LCA_dfs(int u,int pre){
    22     dep[u]=dep[pre]+1,fa[u][0]=pre,l[u]=++idx;
    23     F(i,1,DEG-1)fa[u][i]=fa[fa[u][i-1]][i-1];
    24     for(int i=g[u];~i;i=nxt[i])if(v[i]!=pre)LCA_dfs(v[i],u);
    25     r[u]=++idx;
    26 }
    27 
    28 int LCA(int a,int b){
    29     if(dep[a]>dep[b])a^=b,b^=a,a^=b;
    30     if(dep[a]<dep[b])F(i,0,DEG-1)if((dep[b]-dep[a])&(1<<i))b=fa[b][i];
    31     if(a!=b)for(int i=DEG-1;i<0?a=fa[a][0]:0,i>=0;i--)
    32     if(fa[a][i]!=fa[b][i])a=fa[a][i],b=fa[b][i];
    33     return a;
    34 }
    35 
    36 void fuck(int s,int fa){
    37     dp[s]=sum[s]=0;
    38     for(int i=g[s];~i;i=nxt[i])if(v[i]!=fa)fuck(v[i],s),sum[s]+=dp[v[i]];
    39     dp[s]=sum[s];
    40     for(int i=0;i<vec[s].size();i++){
    41         int uu=p[vec[s][i]].u,vv=p[vec[s][i]].v;
    42         int tmp=ask(l[uu],c1)+ask(l[vv],c1)-ask(l[uu],c2)-ask(l[vv],c2)+sum[s];
    43         dp[s]=max(dp[s],tmp+p[vec[s][i]].w);
    44     }
    45     add(l[s],sum[s],c1),add(r[s],-sum[s],c1);
    46     add(l[s],dp[s],c2),add(r[s],-dp[s],c2);
    47 }
    48 void init(){
    49     F(i,1,n)g[i]=-1,vec[i].clear();ed=idx=0;
    50     F(i,1,n*2)c1[i]=c2[i]=0;
    51 }
    52 
    53 int main(){
    54     scanf("%d",&t);
    55     while(t--){
    56         scanf("%d%d",&n,&m);
    57         init();
    58         F(i,1,n-1)scanf("%d%d",&x,&y),adg(x,y),adg(y,x);
    59         LCA_dfs(1,1);
    60         F(i,1,m){
    61             scanf("%d%d%d",&p[i].u,&p[i].v,&p[i].w);
    62             p[i].lca=LCA(p[i].u,p[i].v);
    63             vec[p[i].lca].push_back(i);
    64         }
    65         fuck(1,0);
    66         printf("%d
    ",dp[1]);
    67     }
    68     return 0;
    69 }
    View Code



  • 相关阅读:
    命令行解释器(shell)
    TensorFlow经典案例2:实现最近邻算法
    TensorFlow经典案例1:基本操作
    TensorBoard在谷歌浏览器显示找不到网页
    Pandas中的DataFrame.filter()
    【转】保证训练集和测试集取到和数据集中相同比例的类别
    数据分析小实践:统计每个国家存在心理健康问题的平均年龄
    TabActivity 切换Activity界面
    Android获取屏幕实际高度跟显示高度,判断Android设备是否拥有虚拟功能键
    非常简单的XML解析(SAX解析、pull解析)
  • 原文地址:https://www.cnblogs.com/bin-gege/p/5696111.html
Copyright © 2011-2022 走看看