(
題意:給定一棵樹,一些鏈,選出最多的鏈不相交。
解法:定義 sum[u] = sim(dp[v]) ( v = son[u] )
dp[u]為u這顆子樹,最多能選的鏈數。
當有一條鏈a,b,lca(a,b)=u
dp[u] = sum[u] - dp[a1] + sum[a1] - dp[a2] … + sum[a]
這樣就可以用樹鏈剖分搞啦~
#pragma comment(linker, "/stack:1024000000,1024000000")
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//#include
//#include
#include
//#pragma comment(linker, "/stack:1024000000,1024000000")
using
namespace
std;
#define lson l, m, rt<<1
#define rson m+1, r, rt<<1|1
#define inf 1e9
#define debug(a) cout << #a" = " << (a) << endl;
#define debugarry(a, n) for (int i = 0; i < (n); i++)
#define clr(x, y) memset(x, y, sizeof x)
#define ll long long
#define ull unsigned long long
#define for(i,a,b) \
for(i=a;a=b;aconst
int maxn = 100000+30;
struct sadg[maxn<<2];
int h[maxn],si;
void add(int u,int v)
int siz[maxn],dep[maxn];
int fa[maxn],son[maxn],top[maxn];
void dfs1(int u,int f,int d)
}int rs[maxn];
void upp(int x,int p)
}int get(int x)
return ret;
}int query(int u,int v)
if( dep[u] > dep[v] ) swap(u,v);
return ret += get(p[v]) - get(p[u]-1);
}int lca(int u,int v)
void init()
int uu[maxn],vv[maxn],val[maxn];
int dp[maxn] , sum[maxn];
vector
q[maxn];
void dfs(int u,int f)
}upp(p[u],sum[u]);
dp[u] = sum[u];
for(int i=0;iint j=q[u][i];
dp[u] = max( dp[u] , query(uu[j],vv[j]) + val[j] );
}upp(p[u],-dp[u]);
}int main()
clr(dp,0);
clr(sum,0);
clr(rs,0);
for(int i=1;i<=n;i++)
q[i].clear();
dfs1(1,-1,1);
dfs2(1,1);
for(int i=0;iscanf("%d%d%d",&uu[i],&vv[i],&val[i]);
q[lca(uu[i],vv[i])].push_back(i);
}dfs(1,-1);
printf("%d\n",dp[1]);
}return
0;}
樹鏈剖分 樹鏈剖分講解
好了,這樣我們就成功解決了對樹上修改查詢邊權或點的問題。下面放上 vector v maxn int size maxn dep maxn val maxn id maxn hson maxn top maxn fa maxn 定義 int edge 1,num 1 struct tree e ma...
HDU3966 樹鏈剖分
題目 aragorn s story 題意 給一棵樹,並給定各個點權的值,然後有3種操作 i c1 c2 k 把c1與c2的路徑上的所有點權值加上k d c1 c2 k 把c1與c2的路徑上的所有點權值減去k q c 查詢節點編號為c的權值 分析 典型的樹鏈剖分題目,先進行剖分,然後用線段樹去維護即...
hdu5029 樹鏈剖分
這題絕對好題。題意很簡單,也很容易想到樹鏈剖分,之後就不太好做了。開始想的是按顏色排序,然後每次處理一種顏色,求出最優解。這樣做的話,最壞情況會退化到n 2,不可接受。之後用線段樹維護,乙個節點只存在一種顏色,而且排序之後能保證在樹中顏色不會交叉,pushdown的時候可以將兩種都不是當前正在處理的...