【jzoj5071】【GDSOI2017第二轮模拟】【奶酪】【树形动态规划】
2017-04-17 22:18
363 查看
题目大意
CJY很喜欢吃奶酪,于是YJC弄到了一些奶酪,现在YJC决定和CJY分享奶酪。
YJC弄到了n-1块奶酪,于是他把奶酪挂在了一棵n个结点的树上,每根树枝上挂一块奶酪,每块奶酪都有重量。
YJC和CJY决定这样分奶酪:首先砍掉一根树枝,把树分成两部分,每人取一部分,然后各自在自己取的那部分树上选择一条路径并取走路径上的奶酪,然后把剩下的奶酪拿去喂老鼠。
两人都想让自己取走总重量尽量大的奶酪,但他们不知道砍掉哪一根树枝最好。所以他们想让你计算,对于每一根树枝,砍掉之后每个人取走的奶酪的总重量的最大值。
解题思路
树形动态规划,枚举删哪一条边,维护往下三条链,往上一条链,子树直径,儿子子树两条直径,各种if即可。
code
#include<set> #include<cmath> #include<cstdio> #include<cstring> #include<algorithm> #define LD double #define LL long long #define ULL unsigned long long #define min(a,b) ((a<b)?a:b) #define max(a,b) ((a>b)?a:b) #define fo(i,j,k) for(int i=j;i<=k;i++) #define fd(i,j,k) for(int i=j;i>=k;i--) #define fr(i,j) for(int i=begin[j];i;i=next[i]) using namespace std; int const mn=4*1e6+9,mm=8*1e6+9,inf=1e9;LL mo=2333333333333333; int n,gra,tag,ansp,begin[mn],to[mm],len[mm],num[mm],next[mm]; LL anss,f[mn][4][2],a[mn][3][2],g[mn],h[mn]; void insert(int u,int v ,int w,int p){ to[++gra]=v; len[gra]=w; num[gra]=p; next[gra]=begin[u]; begin[u]=gra; } void add(int now,int pos,LL far){ fd(i,3,1){ if(f[now][i][0]>far)break; f[now][i+1][0]=f[now][i][0]; f[now][i+1][1]=f[now][i][1]; f[now][i][0]=far; f[now][i][1]=pos; } } void dfs(int now,int pre){ fr(i,now)if(to[i]!=pre){ dfs(to[i],now); add(now,to[i],f[to[i]][1][0]+len[i]); h[now]=max(h[now],h[to[i]]); } h[now]=max(h[now],f[now][1][0]+f[now][2][0]); } LL get(int now,int tag){ fo(i,1,3)if(f[now][i][1]!=tag)return f[now][i][0]; } LL get2(int now,int tag){ if(f[now][1][1]==tag)return f[now][2][0]+f[now][3][0]; else if(f[now][2][1]==tag)return f[now][1][0]+f[now][3][0]; else return f[now][1][0]+f[now][2][0]; } void addh(int now,int pos,LL far){ fd(i,2,1){ if(a[now][i][0]>far)break; a[now][i+1][0]=a[now][i][0]; a[now][i+1][1]=a[now][i][1]; a[now][i][0]=far; a[now][i][1]=pos; } } LL geth(int now,int tag){ fo(i,1,2)if(a[now][i][1]!=tag)return a[now][i][0]; } void dfs2(int now,int pre,LL tmx){ fr(i,now)if(to[i]!=pre) addh(now,to[i],h[to[i]]); fr(i,now)if(to[i]!=pre){ LL tmp=get(now,to[i]); g[to[i]]=max(tmp,g[now])+len[i]; tmp=h[to[i]];LL tmp2=get2(now,to[i]),tmp3=get(now,to[i])+g[now]; tmp2=max(tmp2,tmp3);tmp3=geth(now,to[i]); tmp2=max(tmp2,tmp3); tmp2=max(tmp2,tmx); tmp3=max(tmp,tmp2);LL tmp4=min(tmp,tmp2); anss=(anss+tmp3*23333+tmp4*2333+1ll*233*num[i]*num[i]+23*num[i]+2)%mo; dfs2(to[i],now,tmp2); } } int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%d",&n);int u,v,w; fo(i,1,n-1){ scanf("%d%d%d",&u,&v,&w); insert(u,v,w,i);insert(v,u,w,i); } dfs(1,0); dfs2(1,0,0); printf("%lld",anss); return 0; }
相关文章推荐
- 【JZOJ5068】【GDSOI2017第二轮模拟】树
- 【jzoj5068】【GDSOI2017第二轮模拟】【树】【动态规划】
- 【JZOJ5069】【GDSOI2017第二轮模拟】蛋糕
- 【jzoj5069】【GDSOI2017第二轮模拟】【蛋糕】【莫比乌斯反演】【杜教筛】
- JZOJ 5068. 【GDSOI2017第二轮模拟】树
- [JZOJ5082].【GDSOI2017第三轮模拟】Informatics Training
- 【jzoj5081】【GDSOI2017第三轮模拟】【Travel Plan】【动态规划】
- 【JZOJ5056】【GDSOI2017模拟4.13】黑白广场
- [jzoj5065][GDOI2017第二轮模拟day two] 开房
- 【GDSOI2017模拟】奶酪
- 【jzoj5060】【GDOI2017第二轮模拟day1】【公路建设】【数据结构】
- 【省选专题一】图论 jzoj 5060.【GDOI2017第二轮模拟day1】公路建设 线段树+最小生成树+并查集
- 【JZOJ5058】【GDSOI2017模拟4.13】采蘑菇
- [JZOJ5081]. 【GDSOI2017第三轮模拟】Travel Plan
- 【JZOJ5060】【GDOI2017第二轮模拟day1】公路建设
- 【jzoj5065】【GDOI2017第二轮模拟day2】【开房间】【动态规划】
- [JZOJ5083].【GDSOI2017第三轮模拟】Gift
- 【jzoj5093】【GDSOI2017第四轮模拟day3】【字符串匹配】【哈希】
- 【JZOJ5061】【GDOI2017第二轮模拟day1】最长路径
- 【GDSOI2017第二轮模拟】树