UVALive 6900Road Repair(点分治)
来源:互联网 发布:libevent源码深度剖析 编辑:程序博客网 时间:2024/06/08 12:14
题意:
给定N≤2×104的一棵树,给定描述这棵树的四元组,(u,v,cost,profit),cost,profit≤103
对于树的所有简单路,找到一条简单路满足∑cost≤C≤2×107,且∑profit最大
求这个最大的∑profit
分析:
首先O(n2)暴力肯定要挂,dp背包的话显然C太大不行
我们需要一个带log的算法,考虑点分治
这题与POJ 1741 Tree很像,对于我们枚举的一条到重心的路径,假设这条路径的信息为(c,p)
此时我们需要知道当前子问题中其它到重心的路径(c′,p′)的max{p′},c′≤C−c,如何快速知道这个,可以考虑线段树或者BIT来维护最大值
那么ans=max{p+p′}
−−memset初始化BIT会T,正常回溯即可
代码:
//// Created by TaoSama on 2015-12-18// Copyright (c) 2015 TaoSama. All rights reserved.////#pragma comment(linker, "/STACK:1024000000,1024000000")#include <algorithm>#include <cctype>#include <cmath>#include <cstdio>#include <cstdlib>#include <cstring>#include <iomanip>#include <iostream>#include <map>#include <queue>#include <string>#include <set>#include <vector>using namespace std;#define pr(x) cout << #x << " = " << x << " "#define prln(x) cout << #x << " = " << x << endlconst int N = 2e4 + 10, INF = 0x3f3f3f3f, MOD = 1e9 + 7;const int M = 2e7 + 10;int n, C, ans;void getMax(int &x, int y) {x = max(x, y);}struct BIT { int mx[M]; void del(int i) { for(; i < M; i += i & -i) mx[i] = 0; } void update(int i, int v) { for(; i < M; i += i & -i) getMax(mx[i], v); } int query(int i) { int ret = 0; for(; i; i -= i & -i) getMax(ret, mx[i]); return ret; }} bit;struct Edge { int v, nxt, c, b;} edge[N << 1];int head[N], cnt;void addEdge(int u, int v, int c, int b) { edge[cnt] = (Edge) {v, head[u], c, b}; head[u] = cnt++; edge[cnt] = (Edge) {u, head[v], c, b}; head[v] = cnt++;}bool vis[N];int sz[N], mx[N], centroid;int getAll(int u, int f) { int ret = 1; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(v == f || vis[v]) continue; ret += getAll(v, u); } return ret;}void getCentroid(int u, int f, int all) { sz[u] = 1; mx[u] = 0; for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(v == f || vis[v]) continue; getCentroid(v, u, all); sz[u] += sz[v]; getMax(mx[u], sz[v]); } getMax(mx[u], all - sz[u]); if(!centroid || mx[u] < mx[centroid]) centroid = u;}typedef pair<int, int> P;void getPath(int u, int f, int cost, int profit, vector<P>& path) { if(cost > C) return; path.push_back(P(cost, profit)); for(int i = head[u]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(v == f || vis[v]) continue; getPath(v, u, cost + edge[i].c, profit + edge[i].b, path); }}void solve(int u) { centroid = 0; getCentroid(u, -1, getAll(u, -1)); int s = centroid; vis[s] = true; for(int i = head[s]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(vis[v]) continue; solve(v); } vector<P> dummy; for(int i = head[s]; ~i; i = edge[i].nxt) { int v = edge[i].v; if(vis[v]) continue; vector<P> path; getPath(v, s, edge[i].c, edge[i].b, path); for(P &p : path) getMax(ans, p.second + bit.query(C - p.first)); for(P &p : path) bit.update(p.first, p.second); dummy.insert(dummy.end(), path.begin(), path.end()); } for(P &p : dummy) bit.del(p.first); vis[s] = false;}int main() {#ifdef LOCAL freopen("C:\\Users\\TaoSama\\Desktop\\in.txt", "r", stdin);// freopen("C:\\Users\\TaoSama\\Desktop\\out.txt","w",stdout);#endif ios_base::sync_with_stdio(0); int t; scanf("%d", &t); while(t--) { cnt = 0; memset(head, -1, sizeof head); scanf("%d", &n); for(int i = 1; i < n; ++i) { int u, v, c, b; scanf("%d%d%d%d", &u, &v, &c, &b); addEdge(u, v, c, b); } scanf("%d", &C); ans = 0; solve(1); printf("%d\n", ans); } return 0;}
0 0
- UVALive 6900Road Repair(点分治)
- UVALive 6900 Road Repair [树分治+线段树]
- UVALive 4613 Mountain Road(DP)
- 树分治(点分治+边分治)
- 【Luogu3806】点分治(点分治)
- UVALive 4302 Toll Road
- UVALive 4613 Mountain Road
- poj1741(点分治)
- bzoj3697(点分治)
- poj1741(点分治)
- POJ 3352 Road Construction (缩点)
- 最近点对 (分治)
- poj1741 Tree(点分治)
- 最近点对(分治)
- bzoj 3697(点分治)
- [POJ1741]Tree(点分治)
- bzoj 1468(点分治)
- bzoj 1316(点分治)
- Android命名规范详细
- 问题,值得研究 申请内存不释放没有问题
- Android入门第八篇之GridView(九宫图)
- POJ 1741 Tree(点分治)
- 关于div高度为0使得下部元素侵占空间问题
- UVALive 6900Road Repair(点分治)
- unable to fine a java virtual machine
- 【jQuery】调用show()和hide()方法显示和隐藏元素
- 【jQuery】动画效果的show()和hide()方法
- 【jQuery】调用toggle()方法实现动画切换效果
- Excel表快速转换成JSON字符串
- 【jQuery】使用slideUp()和slideDown()方法的滑动效果
- 【jQuery】使用slideToggle()方法实现图片“变脸”效果
- 51Nod 1163 最高的奖励(贪心+优先队列 & 并差集)