UVALive6900 Road Repair(树的点分治)
题目大概说一棵树,树边有费用和收益两个属性,求一条收益和最大的路径满足费用和不超过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(树的点分治)的更多相关文章
- HDU4812 D Tree(树的点分治)
题目大概说给一棵有点权的树,输出字典序最小的点对,使这两点间路径上点权的乘积模1000003的结果为k. 树的点分治搞了.因为是点权过根的两条路径的LCA会被重复统计,而注意到1000003是质数,所 ...
- CF 322E - Ciel the Commander 树的点分治
树链剖分可以看成是树的边分治,什么是点分治呢? CF322E - Ciel the Commander 题目:给出一棵树,对于每个节点有一个等级(A-Z,A最高),如果两个不同的节点有相同等级的父节点 ...
- hdu 4670 树的点分治
思路:首先当然是要用树的点分治了.根节点为root,那么经过root的合法路径数求出来这题就解决了.因为我们可以用分治枚举根,最后将所有根的路径数加起来就是结果.当然这里的根不是整棵树的根,是子树根. ...
- bzoj 3435: [Wc2014]紫荆花之恋 替罪羊树维护点分治 && AC400
3435: [Wc2014]紫荆花之恋 Time Limit: 240 Sec Memory Limit: 512 MBSubmit: 159 Solved: 40[Submit][Status] ...
- bzoj 2152: 聪聪可可 树的点分治
2152: 聪聪可可 Time Limit: 3 Sec Memory Limit: 259 MBSubmit: 485 Solved: 251[Submit][Status] Descripti ...
- hdu 4812 D Tree(树的点分治)
D Tree Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 102400/102400 K (Java/Others) Total ...
- hdu_5314_Happy King(树的点分治)
题目链接:hdu_5314_Happy King 题意: 给出一颗n个结点的树,点上有权值: 求点对(x,y)满足x!=y且x到y的路径上最大值与最小值的差<=D: 题解: 还是树的点分治,在统 ...
- POJ 1741/1987 树的点分治
树的点分治,主要思想是每次找子树的重心,计算经过根节点的情况数,再减去点对属于同一子树的情况. #include <iostream> #include <vector> #i ...
- poj 1741 树的点分治(入门)
Tree Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 18205 Accepted: 5951 Description ...
随机推荐
- sqlite建表语句(特别是外键问题)
原创 sqlite建表语句(特别是外键问题) 下面图表示两个表关系: //表1User_invitecreate table User_invite(Invite_id INTEGER PRIMAR ...
- PAL/NTSC 制电视广播技术有关知识--FPGA
1.PAL和NTSC的区别 常见的电视信号制式是PAL和NTSC,另外还有SECAM等. NTSC即正交平衡调幅制,PAL为逐行倒像正交平衡调幅制. (1)PAL电视标准 PAL电视标准,每秒25帧 ...
- Dapper.NET 使用简单举例
概述 Dapper是.NET下一个micro的ORM,它和Entity Framework或Nhibnate不同,属于轻量级的,并且是半自动的.也就是说实体类都要自己写.它没有复杂的配置文件,一个单文 ...
- ytu 1058: 三角形面积(带参的宏 练习)
1058: 三角形面积 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 190 Solved: 128[Submit][Status][Web Boar ...
- <转>删除文件夹下所有的.svn文件
当使用了svn版本控制系统后每个目录下都会有一个.svn目录存在,开发完当交付产品或者上传到服务器时一般要把这些目录删除,这里总结了一下在linux和win下的办法. 一.在linux下 删除这些目录 ...
- wp8 入门到精通 仿QQPivot 提示数量
<Grid x:Name="LayoutRoot" Background="White"> <Grid Width="480&quo ...
- (译)【Unity教程】使用Unity开发Windows Phone上的横版跑酷游戏
译者注: 目前移动设备的跨平台游戏开发引擎基本都是采用Cocos2d-x或者Unity.一般而言2d用cocos2d-x 3d用unity,但是对于Windows Phone开发者, cocos2d- ...
- 第一次尝试用 Live Writer 写博客
之前在官网上下载了最新版的Windows Live Writer,可是安装不了,就在其他网站下了一个试试,可以安装,不过却是2009年的版本,很不喜欢,我希望能体验最新版的,回头还得重新下个最新版的安 ...
- AxureRP7.0各类交互效果汇总帖(转)
了便于大家参考,我把这段时间发布分享的所有关于AxureRP7.0的原型做了整理. 以下资源均有对应的RP源文件可以下载. 当然 ,其中有部分是需要通过完成解密游戏[攻略]才能得到下载地址或者下载密码 ...
- Android之TabHost布局(转)
1.概念 盛放Tab的容器就是TabHost.TabHost的实现有两种方式: 第一种继承TabActivity,从TabActivity中用getTabHost()方法获取TabHost.各个Tab ...