[HNOI/AHOI2018]道路
阿新 • • 發佈:2018-11-01
題目
https://www.luogu.org/problemnew/show/P4438
思路
son[i][0]表示i的左兒子(也就是修公路),son[i][1]表示i的右兒子(也就是修鐵路)。
f[i][j][k]表示第i個點到根經過j個未被修復的公路,k個未被修復的鐵路所得到的最小值。
最後用個記憶化搜尋一下即可。
程式碼
#include<cstdio> #include<cstring> #include<algorithm> #define LL long long using namespace std; int n; struct node{LL x,y,z;} a[20010]; int son[20010][5]; LL f[20010][45][45]; LL dfs(int x,int p,int q) { if(x>=n) return a[x-n+1].z*(a[x-n+1].x+p)*(a[x-n+1].y+q); if(f[x][p][q]!=f[n+1][41][41]) return f[x][p][q]; return f[x][p][q]=min(dfs(son[x][0],p,q)+dfs(son[x][1],p,q+1),dfs(son[x][1],p,q)+dfs(son[x][0],p+1,q)); } int main() { int x,y; scanf("%d",&n); memset(f,63,sizeof(f)); for(int i=1;i<n;i++) { scanf("%d %d",&x,&y); if(x<0) x=-x+n-1; if(y<0) y=-y+n-1; son[i][0]=x; son[i][1]=y; } for(int i=1;i<=n;i++) scanf("%lld %lld %lld",&a[i].x,&a[i].y,&a[i].z); printf("%lld",dfs(1,0,0)); }