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 ...
随机推荐
- Cityengine, 3ds MAX, FME
Cityengine 和 3ds MAX 一次只可以导入 (import) 一个模型. FME可以一次导入多个模型,因此可以用它来进行数据整合,然后放到cityengine里头去现实.FZViewer ...
- Centos7 ZooKeeper 安装过程
www.apache.org/dist/上可以下载Hadoop整个生态环境的组件,我下的Zookeeper3.4.6版本 我一般都是在一个虚拟机上将一.二步都做完,然后克隆出来,再到克隆出来的虚拟机上 ...
- iOS - HTTPS接口加密和身份认证
为什么要使用HTTPS代替HTTP HTTPS和HTTP的区别 https协议需要到CA申请证书,一般免费证书很少,需要交费. http是超文本传输协议,信息是明文传输,https则是具有安全性的SS ...
- 网络中文乱码问题 utf-8
// 网络中文乱码问题 utf-8 [string stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
- MVC基础知识 – 1.抽象工厂模式
1.调用规则 2.简单工厂 问题:在List.aspx里怎么new一个业务层? 2.1.再在 02SBLL 解决方案里建一个类库 BLL_Tow,也有一个 Users.cs 2.2.建立一个工厂 2. ...
- WPF样式
<Window x:Class="WpfApplication1.Window1" xmlns="http://schemas.microsoft.com/winf ...
- ASP.NET Web API 数据验证
第一种方式单独为每一个Action做验证 // POST api/values public HttpResponseMessage Post([FromBody]UserInfo userInfo) ...
- 在ubuntu上搭建开发环境4---ubuntu简单的搭建LAMP环境和配置
最近重新安装了Ubuntu,但是之前的LAMP环境自然也就没有了,实在是不想再去编译搭建LAMP环境(这种方法实在是太费时间,而且太容易遇到各种不知道为什么的错误),所以,就去查查有没有什么简单的搭建 ...
- hdu 1698:Just a Hook(线段树,区间更新)
Just a Hook Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total ...
- 使用html5 canvas绘制圆形或弧线
注意:本文属于<html5 Canvas绘制图形入门详解>系列文章中的一部分.如果你是html5初学者,仅仅阅读本文,可能无法较深入的理解canvas,甚至无法顺畅地通读本文.请点击上述链 ...