【jzoj5338】【NOIP2017提高A组模拟8.25】【影子】【点分治】
2017-08-25 11:51
519 查看
description
有必要说明一下,下面的点分治在菊花图上会tle。
solution
直接点分治,维护点权最小值和边权和,按点权最小值排序,两个指针维护一下最大值即可。
code
#include<set> #include<cstdio> #include<cmath> #include<cstring> #include<algorithm> #define LL long long #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=1e5+9,mm=2*1e5+9,mo=1<<30; int t,n,gra,begin[mn],to[mm],len[mm],next[mm],size[mn],vis[mn],cntb,w[mn]; LL ans; void insert(int u,int v,int w){ to[++gra]=v; len[gra]=w; next[gra]=begin[u]; begin[u]=gra; } void gsize(int p,int q){ size[p]=1; fr(i,p)if((to[i]!=q)&&(!vis[to[i]])){ gsize(to[i],p); size[p]+=size[to[i]]; } } int groot(int p,int q,int lim){ fr(i,p)if((to[i]!=q)&&(!vis[to[i]])){ int tmp=groot(to[i],p,lim); if(tmp)return tmp; } if(size[p]>lim)return p; return 0; } struct rec{ int mi; LL sum; friend bool operator<(rec x,rec y){ return x.mi<y.mi; } }; rec a[mn],b[mn],c[mn]; void dfs(int p,int q,int mi,LL sum){ b[++cntb].mi=mi; b[cntb].sum=sum; fr(i,p)if((to[i]!=q)&&(!vis[to[i]])) dfs(to[i],p,min(mi,w[to[i]]),sum+len[i]); } LL calc(rec *a,int cnta,rec *b,int cntb){ LL tmp=0,mx=0; for(int i=cnta,j=cntb+1;i;i--){ while((j>1)&&(b[j-1].mi>=a[i].mi))j--,mx=max(mx,b[j].sum); tmp=max(tmp,a[i].mi*(a[i].sum+mx)); } return tmp; } void solve(int p){ gsize(p,0); p=groot(p,0,size[p]/2); vis[p]=1; int cnta=0; fr(i,p)if(!vis[to[i]]){ cntb=0; dfs(to[i],p,min(w[p],w[to[i]]),len[i]); sort(b+1,b+cntb+1); ans=max(ans,calc(a,cnta,b,cntb)); ans=max(ans,calc(b,cntb,a,cnta)); int cntc=0; for(int j=1,k=1;(j<=cnta)||(k<=cntb);){ cntc++; if((k>cntb)||((j<=cnta)&&(a[j].mi<b[k].mi))){ c[cntc].mi=a[j].mi; c[cntc].sum=a[j].sum; j++; }else{ c[cntc].mi=b[k].mi; c[cntc].sum=b[k].sum; k++; } } cnta=cntc; fo(j,1,cntc){ a[j].mi=c[j].mi; a[j].sum=c[j].sum; } } fr(i,p)if(!vis[to[i]])solve(to[i]); } int main(){ freopen("d.in","r",stdin); freopen("d.out","w",stdout); scanf("%d",&t); fo(cas,1,t){ scanf("%d",&n); fo(i,1,n)scanf("%d",&w[i]),vis[i]=0; gra=0; fo(i,1,n)begin[i]=0; fo(i,1,n-1){ int u,v,w; scanf("%d%d%d",&u,&v,&w); insert(u,v,w); insert(v,u,w); } ans=0; solve(1); printf("%lld\n",ans); } return 0; }
相关文章推荐
- 【JZOJ4929】 【NOIP2017提高组模拟12.18】B
- JZOJ5358. 【NOIP2017提高A组模拟9.12】BBQ
- 【jzoj5247】【NOIP2017提高A组模拟8.10】【计算几何】【二分答案】
- jzoj5399 【NOIP2017提高A组模拟10.7】Confess
- JZOJ5377. 【NOIP2017提高A组模拟9.19】开拓 DP
- JZOJ 5182. 【NOIP2017提高组模拟6.29】码灵鼠
- JZOJ5405. 【NOIP2017提高A组模拟10.10】Permutation
- 【JZOJ 5390】【NOIP2017提高A组模拟9.26】逗气
- jzoj5335 【NOIP2017提高A组模拟8.24】早苗 (递推优化矩乘)
- JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
- JZOJ5354. 【NOIP2017提高A组模拟9.9】导弹拦截
- 【jzoj5231】【NOIP2017模拟A组模拟8.5】【序列问题】 【分治】
- 【JZOJ4922】【NOIP2017提高组模拟12.17】环
- 【JZOJ 5358】【NOIP2017提高A组模拟9.12】BBQ
- JZOJ 4933. 【NOIP2017提高组模拟12.24】C
- 【jzoj5248】【NOIP2017提高A组模拟8.10】【花花的聚会】【动态规划】【可持久化线段树】
- 【JZOJ 5249】【NOIP2017提高A组模拟8.10】文本编辑器
- JZOJ 5373. 【NOIP2017提高A组模拟9.17】信仰是为了虚无之人
- 【jzoj5288】【NOIP2017提高组A组模拟8.17】【球场大佬】
- JZOJ 5406. 【NOIP2017提高A组模拟10.10】Tree