hdu 6201 树分治
来源:互联网 发布:谈谈大数据税务应用 编辑:程序博客网 时间:2024/06/06 09:47
题意:一棵树,边全,点权,点权是书的价格,边权是运费。任选两个点买卖,求最大 利益。
思路:nlogn树分治,当时一看1e5,又是求树上路径的,想也没想直接莽分治,分治的过程中维护最大作为买和卖的利益就好了。
代码:
#include<bits/stdc++.h>using namespace std;#define X first#define Y second#define PB push_back#define MP make_pair#define MEM(a,b) memset(a,b,sizeof(a))typedef long long ll;const ll mod = 1e9+7;const int maxn =1e6+10;int n,t;int ans,root,Max;struct node{ int v,next,w;}edge[maxn*2];int head[maxn],tot,num1,num2;int si[maxn],maxv[maxn],vis[maxn];//vis标记重心int dis[maxn],a[maxn],tmpsell,tmpbuy;void init(){ tot=ans=0;MEM(head,-1);MEM(vis,0);}void add_edge(int u,int v,int w){ edge[tot].v=v;edge[tot].w=w;edge[tot].next=head[u];head[u]=tot++;}//处理子树的大小(固定)void dfssi(int u,int f){ si[u]=1; maxv[u]=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==f||vis[v])continue; dfssi(v,u); si[u]+=si[v]; if(si[v]>maxv[u])maxv[u]=si[v]; }}//找重心(固定)void dfsroot(int r,int u,int f){ if(si[r]-si[u]>maxv[u])//si[r]-si[u]是u上面部分的树的尺寸,跟u的最大孩子比,找到最大孩子的最小差值节点 maxv[u]=si[r]-si[u]; if(maxv[u]<Max)Max=maxv[u],root=u; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v==f||vis[v])continue; dfsroot(r,v,u); }}//求每个点到u的距离(自定义)void dfsdis(int u,int d,int f){ tmpsell=min(tmpsell,d-a[u]); tmpbuy=min(tmpbuy,d+a[u]); for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v; if(v!=f&&!vis[v])//不跨过其他重心 dfsdis(v,d+edge[i].w,u); }}//分边解决一个重心的答案(自定义)int calc(int u,int d){ int ret=0; for(int i=head[u];i!=-1;i=edge[i].next){ int v=edge[i].v,w=edge[i].w; if(!vis[v]){ tmpsell=tmpbuy=1e9+10000; dfsdis(v,w,0); ret=max(ret,-a[u]-tmpsell); ret=max(ret,a[u]-tmpbuy); ret=max(ret,-tmpsell-tmpbuy); } } return ret;}void dfs(int u){ Max=n; dfssi(u,0);//重心预处理 dfsroot(u,u,0);//找重心 vis[root]=1; ans=max(ans,calc(root,0));//合并贡献(固定?) for(int i=head[root];i!=-1;i=edge[i].next){ int v=edge[i].v; if(!vis[v])dfs(v); }}int main(){ scanf("%d",&t); while(t--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%d",&a[i]); int u,v,w; init(); for(int i=1;i<n;i++){ scanf("%d%d%d",&u,&v,&w); add_edge(u,v,w);add_edge(v,u,w); } dfs(1); printf("%d\n",ans); } return 0;}
阅读全文
0 0
- hdu 6201 树分治
- hdu 4812 树分治
- HDU 4916 树分治
- HDU 5102 树分治
- hdu 6035 树分治
- HDU 4812 D Tree (树分治之点分治)
- hdu 4670 (树的分治)
- 【HDU 4812】D Tree【树的分治】
- hdu 4871 Shortest-path tree 树分治
- HDU 4812 D Tree(树分治)
- hdu-4812(树分治 点权)
- HDU 4812 D Tree [树分治]
- HDU 5977 树的分治+子集枚举
- hdu-5977 Garden of Eden(树分治)
- HDU 5977 树分治+状态压缩
- 树分治-点分治
- hdu 1007 分治
- hdu 1007 (分治)
- 一看你就懂,超详细java中的ClassLoader详解
- 聚集索引和非聚集索引(整理)
- Android Studio官方默认快捷键设置(Windows/Mac)
- 苹果发布会证实,他们把脸部检测技术和ARKit结合在了一起
- 感悟
- hdu 6201 树分治
- HTML+CSS
- 第二周项目二
- python笔记_2
- Linux搭建Java服务器环境-Nginx安装
- Github使用教程
- 我那已经逝去的两年
- Spring 小总结
- Gnome安装及个性化设置