codeforces 294E Shaass the Great (树形dp,好题)
来源:互联网 发布:网易公开课 网络不给力 编辑:程序博客网 时间:2024/04/27 20:45
题意:
给出一棵树,每条边有一个权值,现在要将树的某个边打断,然后重新建一条等长的边在某两点间,要求建完边的图形也要是树。求使得所有点两两距离和最短的方案。
题解:
我们分析如果某条边打断,那么就分成了两棵树,我们假设断掉的是u,v两点的边,那么两两距离和可以化成这个公式:
S = { u的树中任意两点距离和 }+{ v的树中任意两点的距离和 } + { u树中任意点到u的距离和 * v的节点数} + { v树中任意点到v的距离和 * u的节点数 } + { u的节点数 * v的节点数 * uv之间的距离 }
这题可以说把数上的操作弄到了极致。设这样的状态dp[u][3] 0表示u的子树孩子的数量,1u的子树的每个孩子到这个点的距离和,2表示u的子树两两点距离的和。
这个处理非常的有技巧,具体看代码。
#include<iostream>#include<math.h>#include<stdio.h>#include<algorithm>#include<string.h>#include<vector>#include<map>using namespace std;typedef long long ll;const int oo=0x3f3f3f3f;const ll OO=1LL<<61;const ll MOD=2147483647;const int maxn=5005;ll dp[maxn][3];///2表示任意两点的距离和,1任意点到i的距离和,0表示子树的孩子数struct EDGE{ int v,next; ll w;}E[maxn<<1];int head[maxn],tol;int U[maxn],V[maxn];ll C[maxn];void add_edge(int u,int v,ll w){ E[tol].v=v; E[tol].w=w; E[tol].next=head[u]; head[u]=tol++;}void Init(){ memset(head,-1,sizeof head); tol=0;}void dfs(int u,int pre){ dp[u][0]=dp[u][1]=dp[u][2]=0; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(v==pre)continue; dfs(v,u); dp[u][2]+=dp[v][2]+dp[v][1]*dp[u][0]+dp[v][0]*dp[u][1]+dp[u][0]*dp[v][0]*E[i].w; dp[u][1]+=dp[v][1]+E[i].w*dp[v][0]; dp[u][0]+=dp[v][0]; } dp[u][0]++;///这个节点还没加,所有任意点到这个节点的距离要加在dp[u][2]中 dp[u][2]+=dp[u][1];}void dfsm(int u,int pre,ll& mi){ mi=min(mi,dp[u][1]); for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v; if(v==pre)continue; dp[v][1]=dp[v][1]+(dp[u][1]-dp[v][1]-E[i].w*dp[v][0])+(dp[u][0]-dp[v][0])*E[i].w; dp[v][0]=dp[u][0]; dfsm(v,u,mi); }}int main(){ int n; ll c; while(scanf("%d",&n)!=EOF) { Init(); for(int i=1;i<=n-1;i++) { scanf("%d %d %I64d",&U[i],&V[i],&C[i]); add_edge(U[i],V[i],C[i]); add_edge(V[i],U[i],C[i]); } ll ans=OO; for(int i=1;i<=n-1;i++) { ll mi=OO; dfs(U[i],V[i]); dfsm(U[i],V[i],mi); ll s1=(n-dp[U[i]][0])*mi+dp[U[i]][2]; mi=OO; dfs(V[i],U[i]); dfsm(V[i],U[i],mi); ll s2=(n-dp[V[i]][0])*mi+dp[V[i]][2]; ll sum=s1+s2+dp[U[i]][0]*dp[V[i]][0]*C[i]; ans=min(ans,sum); } cout<<ans<<endl; } return 0;}/**31 2 21 3 461 2 12 3 13 4 14 5 15 6 161 3 12 3 13 4 1004 5 24 6 1*/
0 0
- codeforces 294E Shaass the Great (树形dp,好题)
- 【树形DP】 CodeForces 294E Shaass the Great
- Codeforces 294E Shaass the Great 树形dp(水
- CF 294E - Shaass the Great 树形dp
- Codeforces Round #294 (Div.2) E Shaass the Great
- CF 294E Shaass the Great【Tree】
- Codeforces 789E The Great Mixing【Bfs+dp】
- Codeforces Round #396 (Div. 2)E(树形dp,按位运算,好题)
- codeforces 23E 树形DP
- codeforces 23E 树形DP
- 树的重心 Shaass the Great
- codeforces 294B Shaass and Bookshelf (暴力dp)
- codeforces 294B B. Shaass and Bookshelf(dp)
- codeforces 23E Tree (树形dp)
- Codeforces Round #407 (Div. 2) E. The Great Mixing [bfs]
- Codeforces 710E Generate a String【dp】好题!
- codeforces Round 21 808E. Selling Souvenirs 【dp好题】
- Codeforces 320E Kalila and Dimna in the Logging Industry【思维+贪心+斜率优化Dp】好题!
- WOJ 1003 - Birth of Noah
- Android手机分辨率基础知识(DPI,DIP计算)
- Sql server best practise for Index
- Codeforces Round #291 (Div. 2) -- B. Han Solo and Lazer Gun (计算几何~暴力)
- 散
- codeforces 294E Shaass the Great (树形dp,好题)
- iOS 上架流程(三)
- HDU--4704 Sum【费马小定理,快速幂】
- Web Service概述
- Tomcat 报错 (The tomcat server configuration at /Servers/Tomcat v7.0 Server at localhost-config is mi)
- xxxSchedule-1-三层架构
- codevs 1403 新三国争霸
- SQL Server2008Microsoft SQL server,错误18456解决办法
- 新团队的组建