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 ...
随机推荐
- 重写List集合的ToString方法
重写方法: public class MyList<T> : List<T> where T : IConvertible { public override string T ...
- python基础——模块
python基础——模块 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文 ...
- Retrofit学习入门
Retrofit的使用 设置权限与添加依赖 定义请求接口 通过创建一个retrofit生成一个接口的实现类(动态代理) 调用接口请求数据 设置权限与添加依赖 权限:首先确保在AndroidManife ...
- 资源监控工具--spotlight
1.被监控服务器为Ubuntu server,先在服务器上创建一个用户,专门用于监控使用! 因为远程监控服务器,需要获取服务器的资源,所以必须要有权限.使用文档明确说明,不能使用root用户,但是我用 ...
- C#关键字params
using System; using System.Threading; namespace Test { /// <summary> /// params用法: 1.用来修饰方法的参数 ...
- Hybrid App是如何实现网页语言与程序语言的混合?谁占主体?
[编者按]本文作者@徐珂铭,一位看好Html5的移动互联网的从业人士.喜爱玩技术,会点JAVA.HTML及CSS,有自己的想法及姑且能表达想法的文字,因此有了自己的文章. 基于HTML5的Web Ap ...
- Android中Thread和Service的区别zz
1). Thread:Thread 是程序执行的最小单元,它是分配CPU的基本单位.可以用 Thread 来执行一些异步的操作. 2). Service:Service 是android的一种机制,当 ...
- WebStorm 有哪些过人之处?
作者:方应杭链接:https://www.zhihu.com/question/20936155/answer/16654794来源:知乎著作权归作者所有,转载请联系作者获得授权. 先说缺点吧: 常驻 ...
- Web API 使用上安全吗?
Web API入门指南有些朋友回复问了些安全方面的问题,安全方面可以写的东西实在太多了,这里尽量围绕着Web API的安全性来展开,介绍一些安全的基本概念,常见安全隐患.相关的防御技巧以及Web AP ...
- <转>FreeMarker内置函数
一. Sequence的内置函数1. sequence?first 返回sequence的第一个值.2. sequence?last 返回sequence的最后一个值.3. sequence?reve ...