【opencup】XVI Open Cup named after E.V. Pankratiev. GP of SPB K.Captain Tarjan【树形dp】
2016-11-04 18:58
483 查看
题目大意:给一棵N个节点的树,你可以选择任意一个点作为根然后树链剖分(树链剖分的定义:如果这个点不是叶子,则其中恰好一条边为重边,其余均为轻边),剖分的方式由你定。然后接下来有M对(u,v),定义(u,v)为树上节点u到节点v的最短路径。现在你要确定一个剖分方案,使得所有对(u,v)经过的轻边个数之和最小,经过多次算多次。输出个数之和。N,M∈[1,1e5]
sb题,100分钟后才过居然还在opencup的vp上拿了fb。
PS:经过多次算一次已经最大个数之和均是一种做法。
sb题,100分钟后才过居然还在opencup的vp上拿了fb。
PS:经过多次算一次已经最大个数之和均是一种做法。
#include <bits/stdc++.h> using namespace std ; typedef long long LL ; typedef pair < int , int > pii ; #define clr( a , x ) memset ( a , x , sizeof a ) const int MAXN = 100005 ; vector < pii > G[MAXN] ; LL dp[MAXN] , dp2[MAXN] , maxc[MAXN] ; LL Ldp[MAXN] , Rdp[MAXN] , Lmaxc[MAXN] , Rmaxc[MAXN] ; int c[MAXN] ; int siz[MAXN] ; int son[MAXN] ; int pre[MAXN] ; int top[MAXN] ; int dep[MAXN] ; int n , m ; LL ans ; void predfs ( int u , int f ) { siz[u] = 1 ; son[u] = 0 ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i].first ; if ( v == f ) continue ; pre[v] = u ; dep[v] = dep[u] + 1 ; predfs ( v , u ) ; siz[u] += siz[v] ; if ( siz[v] > siz[son[u]] ) son[u] = v ; } } void rebuild ( int u , int top_element ) { top[u] = top_element ; if ( son[u] ) rebuild ( son[u] , top_element ) ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i].first ; if ( v != pre[u] && v != son[u] ) rebuild ( v , v ) ; } } int get_lca ( int x , int y ) { while ( top[x] != top[y] ) { if ( dep[top[x]] > dep[top[y]] ) x = pre[top[x]] ; else y = pre[top[y]] ; } return dep[x] < dep[y] ? x : y ; } void dfs1 ( int u ) { for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i].first ; if ( v == pre[u] ) continue ; dfs1 ( v ) ; G[u][i].second = c[v] ; c[u] += c[v] ; } } void dfs2 ( int u ) { dp[u] = maxc[u] = 0 ; for ( int i = 0 ; i < G[u].size () ; ++ i ) { int v = G[u][i].first ; if ( v == pre[u] ) continue ; dfs2 ( v ) ; dp[u] += dp[v] + G[u][i].second ; maxc[u] = max ( maxc[u] , G[u][i].second + 0LL ) ; } dp[u] -= maxc[u] ; } void dfs3 ( int u , int cost ) { int n = G[u].size () ; Ldp[0] = 0 ; Rdp[n - 1] = 0 ; Lmaxc[0] = 0 ; Rmaxc[n - 1] = 0 ; for ( int i = 1 ; i < n ; ++ i ) { int v = G[u][i - 1].first ; if ( v == pre[u] ) { Ldp[i] = Ldp[i - 1] ; Lmaxc[i] = Lmaxc[i - 1] ; } else { Ldp[i] = Ldp[i - 1] + dp[v] + G[u][i - 1].second ; Lmaxc[i] = max ( Lmaxc[i - 1] , G[u][i - 1].second + 0LL ) ; } } for ( int i = n - 2 ; i >= 0 ; -- i ) { int v = G[u][i + 1].first ; if ( v == pre[u] ) { Rdp[i] = Rdp[i + 1] ; Rmaxc[i] = Rmaxc[i + 1] ; } else { Rdp[i] = Rdp[i + 1] + dp[v] + G[u][i + 1].second ; Rmaxc[i] = max ( Rmaxc[i + 1] , G[u][i + 1].second + 0LL ) ; } } for ( int i = 0 ; i < n ; ++ i ) { int v = G[u][i].first ; if ( v == pre[u] ) continue ; dp2[v] = dp2[u] + Ldp[i] + Rdp[i] + cost - max ( max ( Lmaxc[i] , Rmaxc[i] ) , cost + 0LL ) ; ans = min ( ans , dp2[v] + dp[v] + maxc[v] + G[u][i].second - max ( maxc[v] , 0LL + G[u][i].second ) ) ; } for ( int i = 0 ; i < n ; ++ i ) { int v = G[u][i].first ; if ( v == pre[u] ) continue ; dfs3 ( v , G[u][i].second ) ; } } void solve () { for ( int i = 1 ; i <= n ; ++ i ) { G[i].clear () ; c[i] = 0 ; } for ( int i = 1 ; i < n ; ++ i ) { int u , v ; scanf ( "%d%d" , &u , &v ) ; G[u].push_back ( pii ( v , 0 ) ) ; G[v].push_back ( pii ( u , 0 ) ) ; } predfs ( 1 , 1 ) ; rebuild ( 1 , 1 ) ; for ( int i = 0 ; i < m ; ++ i ) { int u , v ; scanf ( "%d%d" , &u , &v ) ; c[u] ++ ; c[v] ++ ; int lca = get_lca ( u , v ) ; c[lca] -= 2 ; } dp2[1] = 0 ; dfs1 ( 1 ) ; dfs2 ( 1 ) ; ans = dp[1] ; dfs3 ( 1 , 0 ) ; printf ( "%lld\n" , ans ) ; } int main () { freopen ( "treepaths.in" , "r" , stdin ) ; freopen ( "treepaths.out" , "w" , stdout ) ; while ( ~scanf ( "%d%d" , &n , &m ) ) solve () ; return 0 ; }
相关文章推荐
- XVI Open Cup named after E.V. Pankratiev. GP of SPB
- XVI Open Cup named after E.V. Pankratiev. GP of Eurasia
- XVI Open Cup named after E.V. Pankratiev. GP of Siberia
- XVI Open Cup named after E.V. Pankratiev. GP of Peterhof
- XVI Open Cup named after E.V. Pankratiev. GP of Ukraine
- XVII Open Cup named after E.V. Pankratiev. GP of SPb
- XVI Open Cup named after E.V. Pankratiev. GP of Ekaterinburg
- XIII Open Cup named after E.V. Pankratiev. GP of SPb
- XIV Open Cup named after E.V. Pankratiev. GP of SPb
- XV Open Cup named after E.V. Pankratiev. GP of Three Capitals
- XII Open Cup named after E.V. Pankratiev. GP of Eastern Europe (AMPPZ-2012)
- XV Open Cup named after E.V. Pankratiev. GP of Tatarstan
- XIV Open Cup named after E.V. Pankratiev. GP of America
- XIII Open Cup named after E.V. Pankratiev. GP of America
- 【找规律】【递归】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem F. Doubling
- XIII Open Cup named after E.V. Pankratiev. GP of Asia and South Caucasus
- 【枚举】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem D. Cutting Potatoes
- XVII Open Cup named after E.V. Pankratiev. GP of Tatarstan
- XVII Open Cup named after E.V. Pankratiev. GP of Two Capitals
- 【推导】【贪心】XVII Open Cup named after E.V. Pankratiev Stage 4: Grand Prix of SPb, Sunday, Octorber 9, 2016 Problem H. Path or Coloring