题目大概说一棵树,树边有费用和收益两个属性,求一条收益和最大的路径满足费用和不超过C。

树上任意两点的路径都可以看成是过某一个子树根的路径,显然树分治。

治的时候要解决的一个问题是,找到费用小于等于某个数且收益最大的值。

这个很容易想到用线段树,不过不想写线段树。。

想了想,想到可以先排序,从小到大去找,之前找到哪现在就继续从那儿开始找,这样最多也就遍历一遍待查找数组,具体看代码。

两次排序占大头,最后时间复杂度是O(nlog2n)。

WA了一次,因为只考虑了两端都过根的路径,忽略了一端点是根的路径。。之前写树分治也是因为这个WA。。

 #include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define INF (1<<30)
#define MAXN 22222
struct Edge{
int v,b,c,next;
}edge[MAXN<<];
int NE,head[MAXN];
void addEdge(int u,int v,int b,int c){
edge[NE].v=v; edge[NE].b=b; edge[NE].c=c; edge[NE].next=head[u];
head[u]=NE++;
}
bool vis[MAXN];
int size[MAXN];
void getsize(int u,int fa){
size[u]=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==fa || vis[v]) continue;
getsize(v,u);
size[u]+=size[v];
}
}
int mm,cen;
void getcen(int u,int fa,int &tot){
int res=tot-size[u];
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==fa || vis[v]) continue;
getcen(v,u,tot);
res=max(res,size[v]);
}
if(res<mm){
mm=res;
cen=u;
}
}
int getcen(int u){
getsize(u,u);
mm=INF;
getcen(u,u,size[u]);
return cen;
}
struct Rec{
int b,c;
bool operator<(const Rec &r)const{
return c<r.c;
}
}ra[MAXN],rb[MAXN];
int tot,an,bn;
void dfs(int u,int fa,int benfit,int cost){
rb[bn].b=benfit;
rb[bn].c=cost;
bn++;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(v==fa || vis[v]) continue;
dfs(v,u,benfit+edge[i].b,cost+edge[i].c);
}
}
int ans;
void conqur(int u){
an=;
ra[].b=; ra[].c=;
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
bn=;
dfs(v,v,edge[i].b,edge[i].c);
sort(ra,ra+an);
sort(rb,rb+bn);
int pa=an-,pb=;
while(pb<bn){
int mx=-;
for(int j=pa; j>=; --j){
if(ra[j].c+rb[pb].c<=tot){
if(mx<ra[j].b+rb[pb].b){
mx=ra[j].b+rb[pb].b;
pa=j;
}
}
}
if(mx==-) break;
ans=max(ans,mx);
++pb;
}
for(int j=; j<bn; ++j){
ra[an++]=rb[j];
}
}
}
void divide(int u){
u=getcen(u);
vis[u]=;
conqur(u);
for(int i=head[u]; i!=-; i=edge[i].next){
int v=edge[i].v;
if(vis[v]) continue;
divide(v);
}
}
int main(){
int t,n,a,b,c,d;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
NE=;
memset(head,-,sizeof(head));
for(int i=; i<n; ++i){
scanf("%d%d%d%d",&a,&b,&c,&d);
addEdge(a,b,d,c);
addEdge(b,a,d,c);
}
scanf("%d",&tot);
ans=;
memset(vis,,sizeof(vis));
divide();
printf("%d\n",ans);
}
return ;
}

UVALive6900 Road Repair(树的点分治)的更多相关文章

  1. HDU4812 D Tree(树的点分治)

    题目大概说给一棵有点权的树,输出字典序最小的点对,使这两点间路径上点权的乘积模1000003的结果为k. 树的点分治搞了.因为是点权过根的两条路径的LCA会被重复统计,而注意到1000003是质数,所 ...

  2. CF 322E - Ciel the Commander 树的点分治

    树链剖分可以看成是树的边分治,什么是点分治呢? CF322E - Ciel the Commander 题目:给出一棵树,对于每个节点有一个等级(A-Z,A最高),如果两个不同的节点有相同等级的父节点 ...

  3. hdu 4670 树的点分治

    思路:首先当然是要用树的点分治了.根节点为root,那么经过root的合法路径数求出来这题就解决了.因为我们可以用分治枚举根,最后将所有根的路径数加起来就是结果.当然这里的根不是整棵树的根,是子树根. ...

  4. bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400

    3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec  Memory Limit: 512 MBSubmit: 159  Solved: 40[Submit][Status] ...

  5. bzoj 2152: 聪聪可可 树的点分治

    2152: 聪聪可可 Time Limit: 3 Sec  Memory Limit: 259 MBSubmit: 485  Solved: 251[Submit][Status] Descripti ...

  6. hdu 4812 D Tree(树的点分治)

    D Tree Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total ...

  7. hdu_5314_Happy King(树的点分治)

    题目链接:hdu_5314_Happy King 题意: 给出一颗n个结点的树,点上有权值: 求点对(x,y)满足x!=y且x到y的路径上最大值与最小值的差<=D: 题解: 还是树的点分治,在统 ...

  8. POJ 1741/1987 树的点分治

    树的点分治,主要思想是每次找子树的重心,计算经过根节点的情况数,再减去点对属于同一子树的情况. #include <iostream> #include <vector> #i ...

  9. poj 1741 树的点分治(入门)

    Tree Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 18205   Accepted: 5951 Description ...

随机推荐

  1. sqlite建表语句(特别是外键问题)

    原创  sqlite建表语句(特别是外键问题) 下面图表示两个表关系: //表1User_invitecreate table User_invite(Invite_id INTEGER PRIMAR ...

  2. PAL/NTSC 制电视广播技术有关知识--FPGA

    1.PAL和NTSC的区别 常见的电视信号制式是PAL和NTSC,另外还有SECAM等. NTSC即正交平衡调幅制,PAL为逐行倒像正交平衡调幅制. (1)PAL电视标准  PAL电视标准,每秒25帧 ...

  3. Dapper.NET 使用简单举例

    概述 Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的.也就是说实体类都要自己写.它没有复杂的配置文件,一个单文 ...

  4. ytu 1058: 三角形面积(带参的宏 练习)

    1058: 三角形面积 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 190  Solved: 128[Submit][Status][Web Boar ...

  5. <转>删除文件夹下所有的.svn文件

    当使用了svn版本控制系统后每个目录下都会有一个.svn目录存在,开发完当交付产品或者上传到服务器时一般要把这些目录删除,这里总结了一下在linux和win下的办法. 一.在linux下 删除这些目录 ...

  6. wp8 入门到精通 仿QQPivot 提示数量

    <Grid x:Name="LayoutRoot" Background="White"> <Grid Width="480&quo ...

  7. (译)【Unity教程】使用Unity开发Windows Phone上的横版跑酷游戏

    译者注: 目前移动设备的跨平台游戏开发引擎基本都是采用Cocos2d-x或者Unity.一般而言2d用cocos2d-x 3d用unity,但是对于Windows Phone开发者, cocos2d- ...

  8. 第一次尝试用 Live Writer 写博客

    之前在官网上下载了最新版的Windows Live Writer,可是安装不了,就在其他网站下了一个试试,可以安装,不过却是2009年的版本,很不喜欢,我希望能体验最新版的,回头还得重新下个最新版的安 ...

  9. AxureRP7.0各类交互效果汇总帖(转)

    了便于大家参考,我把这段时间发布分享的所有关于AxureRP7.0的原型做了整理. 以下资源均有对应的RP源文件可以下载. 当然 ,其中有部分是需要通过完成解密游戏[攻略]才能得到下载地址或者下载密码 ...

  10. Android之TabHost布局(转)

    1.概念 盛放Tab的容器就是TabHost.TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab ...