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 ...
随机推荐
- 解决安卓TextView异常换行,参差不齐等问题
参考:http://blog.csdn.net/u012286242/article/details/28429267?utm_source=tuicool&utm_medium=referr ...
- 二、JavaScript语言--JS实践--倒计时效果
主要内容:分析不同倒计时效果的计算思路及方法,掌握日期对象Date,获取时间的方法,计算时差的方法,实现不同的倒时计效果. Javascript 日期对象: Date()返回当前的日期和时间 getY ...
- bt和wifi的共存
转自:http://bbs.52rd.com/Thread-291892-1-1.html 蓝牙和802.11b/g/n都可能工作在2.4GISM,可能互相干扰.干扰的典型应用之一是VOIP,用手机的 ...
- PHP实现执行定时任务的几种思路详解
转:https://segmentfault.com/a/1190000002955509 PHP本身是没有定时功能的,PHP也不能多线程.PHP的定时任务功能必须通过和其他工具结合才能实现,例如Wo ...
- 跳出IFrame几种方式
1. <script type="text/javascript"> if (top.location !== self.location) { top.locatio ...
- android开子线程避免出现main错误
Runnable SonThread=new Runnable() { @Override public void run() { // TODO Auto-generated method stub ...
- 注解:【有连接表的】Hibernate单向1->N关联
Person与Address关联:单向1->N,[有连接表的] Person.java package org.crazyit.app.domain; import java.util.Hash ...
- 接口API测试和返回值JSON解析的插件
火狐插件1. HttpRequest作用:接口API测试例子:http://192.168.10.61:8080/ZHCS/user/loginApp.do?phone=admin&pwd ...
- tcflush 功能(转)
tcflush() 丢弃要写入引用的对象,但是尚未传输的数据,或者收到但是尚未读取的数据,取决于 queue_selector 的值: TCIFLUSH 刷新收到的数据但是不读 TCOFLUSH 刷新 ...
- Eclipse的详细安装步骤
第一种:这个方法是在线安装的 第二种:下载完整免安装包 首先打开网址:http://www.eclipse.org/ 然后在这里我就选择64位的安装,就以安装安卓开发的举例: 然后下载即可: