其实是求树上的路径间的数据第K大的题目。
果断主席树 + LCA。
初始流量是这条路径上的最小值。
若a<=b,显然直接为s->t建立pipe可以使流量最优;
否则,对【0, 10**4】二分得到boundry,使得boundry * n_edge - sum_edge <= k/b, 或者建立s->t,然后不断extend s->t。

 /* 4729 */
#include <iostream>
#include <sstream>
#include <string>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <vector>
#include <deque>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <ctime>
#include <cstring>
#include <climits>
#include <cctype>
#include <cassert>
#include <functional>
#include <iterator>
#include <iomanip>
using namespace std;
//#pragma comment(linker,"/STACK:102400000,1024000") #define sti set<int>
#define stpii set<pair<int, int> >
#define mpii map<int,int>
#define vi vector<int>
#define pii pair<int,int>
#define vpii vector<pair<int,int> >
#define rep(i, a, n) for (int i=a;i<n;++i)
#define per(i, a, n) for (int i=n-1;i>=a;--i)
#define clr clear
#define pb push_back
#define mp make_pair
#define fir first
#define sec second
#define all(x) (x).begin(),(x).end()
#define SZ(x) ((int)(x).size())
// #define lson l, mid, rt<<1
// #define rson mid+1, r, rt<<1|1 typedef struct {
int v, c, nxt;
} edge_t; const int maxn = 1e5+;
const int m = ;
const int maxm = maxn * ;
int T[maxn];
int lson[maxm], rson[maxm], c[maxm], sum[maxm];
int head[maxn], l;
edge_t E[maxn<<];
int tot, n, q;
int beg[maxn];
int V[maxn<<], D[maxn<<], top;
int dp[][maxn<<]; void init() {
memset(head, -, sizeof(head));
l = top = ;
tot = ;
} int Build(int l, int r) {
int rt = tot++; c[rt] = sum[rt] = ;
if (l == r)
return rt; int mid = (l + r) >> ; lson[rt] = Build(l, mid);
rson[rt] = Build(mid+, r); return rt;
} int Insert(int rt, int x, int val) {
int nrt = tot++, ret = nrt;
int l = , r = m - , mid; c[nrt] = c[rt] + ;
sum[nrt] = sum[rt] + val;
while (l < r) {
mid = (l + r) >> ;
if (x <= mid) {
lson[nrt] = tot++;
rson[nrt] = rson[rt];
nrt = lson[nrt];
rt = lson[rt];
r = mid;
} else {
lson[nrt] = lson[rt];
rson[nrt] = tot++;
nrt = rson[nrt];
rt = rson[rt];
l = mid + ;
}
c[nrt] = c[rt] + ;
sum[nrt] = sum[rt] + val;
} return ret;
} int Query_kth(int urt, int vrt, int frt, int k) {
int l = , r = m - , mid;
int tmp; while (l < r) {
mid = (l + r) >> ;
tmp = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << );
if (tmp >= k) {
urt = lson[urt];
vrt = lson[vrt];
frt = lson[frt];
r = mid;
} else {
k -= tmp;
urt = rson[urt];
vrt = rson[vrt];
frt = rson[frt];
l = mid + ;
}
} return l;
} int Query_Bound(int urt, int vrt, int frt, int delta) {
int l = , r = m - , mid;
int cc = , csum = ;
int tc, tsum;
int ans = , tmp; while (l < r) {
mid = (l + r) >> ;
tc = c[lson[urt]] + c[lson[vrt]] - (c[lson[frt]] << );
tsum = sum[lson[urt]] + sum[lson[vrt]] - (sum[lson[frt]] << );
tmp = mid*(tc+cc)-(tsum+csum);
if (tmp <= delta)
ans = max(ans, mid);
if (mid*(tc+cc)-(tsum+csum) >= delta) {
urt = lson[urt];
vrt = lson[vrt];
frt = lson[frt];
r = mid;
} else {
urt = rson[urt];
vrt = rson[vrt];
frt = rson[frt];
cc += tc;
csum += tsum;
l = mid + ;
}
} return ans;
} void addEdge(int u, int v, int c) {
E[l].v = v;
E[l].c = c;
E[l].nxt = head[u];
head[u] = l++; E[l].v = u;
E[l].c = c;
E[l].nxt = head[v];
head[v] = l++;
} void dfs(int u, int fa, int dep) {
int v, k; V[++top] = u;
D[top] = dep;
beg[u] = top; for (k=head[u]; k!=-; k=E[k].nxt) {
v = E[k].v;
if (v == fa)
continue;
T[v] = Insert(T[u], E[k].c, E[k].c);
dfs(v, u, dep+);
V[++top] = u;
D[top] = dep;
}
} void Init_RMQ(int n) {
int i, j; for (i=; i<=n; ++i)
dp[][i] = i;
for (j=; (<<j)<=n; ++j)
for (i=; i+(<<j)-<=n; ++i)
if (D[dp[j-][i]] < D[dp[j-][i+(<<(j-))]])
dp[j][i] = dp[j-][i];
else
dp[j][i] = dp[j-][i+(<<(j-))];
} int RMQ(int l, int r) {
if (l > r)
swap(l, r); int k = ; while (<<(k+) <= r-l+)
++k; if (D[dp[k][l]] < D[dp[k][r-(<<k)+]])
return V[dp[k][l]];
else
return V[dp[k][r-(<<k)+]];
} void solve() {
T[] = Build(, m - );
dfs(, , );
Init_RMQ(top); int u, v, k, a, b;
int lca;
int ans, tmp, org; while (q--) {
scanf("%d %d %d %d %d", &u, &v, &k, &a, &b);
lca = RMQ(beg[u], beg[v]);
org = Query_kth(T[u], T[v], T[lca], );
#ifndef ONLINE_JUDGE
// printf("f = %d\n", lca);
#endif
if (a <= b) {
ans = org + k / a;
} else {
ans = org;
if (k >= a)
ans += + (k-a)/b;
tmp = Query_Bound(T[u], T[v], T[lca], k/b);
#ifndef ONLINE_JUDGE
// printf("org = %d, ans = %d, bound = %d\n", org, ans, tmp);
#endif
ans = max(ans, tmp);
}
printf("%d\n", ans);
}
} int main() {
ios::sync_with_stdio(false);
#ifndef ONLINE_JUDGE
freopen("data.in", "r", stdin);
freopen("data.out", "w", stdout);
#endif int t;
int u, v, c; scanf("%d", &t);
rep(tt, , t+) {
init();
scanf("%d %d", &n, &q);
rep(i, , n) {
scanf("%d %d %d", &u, &v, &c);
addEdge(u, v, c);
}
printf("Case #%d:\n", tt);
solve();
} #ifndef ONLINE_JUDGE
printf("time = %d.\n", (int)clock());
#endif return ;
}

数据发生器。

 from copy import deepcopy
from random import randint, shuffle
import shutil
import string def GenDataIn():
with open("data.in", "w") as fout:
t = 10
bound = 10**4
fout.write("%d\n" % (t))
for tt in xrange(t):
n = randint(100, 200)
q = randint(100, 200)
fout.write("%d %d\n" % (n, q))
ust = [1]
vst = range(2, n+1)
for i in xrange(1, n):
idx = randint(0, len(ust)-1)
u = ust[idx]
idx = randint(0, len(vst)-1)
v = vst[idx]
ust.append(v)
vst.remove(v)
c = randint(0, bound-1)
fout.write("%d %d %d\n" % (u, v, c))
for i in xrange(q):
u = randint(1, n)
while True:
v = randint(1, n)
if v!=u:
break
k = randint(0, bound)
a = randint(1, bound)
b = randint(1, bound)
fout.write("%d %d %d %d %d\n" % (u, v, k, a, b)) def MovDataIn():
desFileName = "F:\eclipse_prj\workspace\hdoj\data.in"
shutil.copyfile("data.in", desFileName) if __name__ == "__main__":
GenDataIn()
MovDataIn()

【HDOJ】4729 An Easy Problem for Elfness的更多相关文章

  1. 数据结构(主席树):HDU 4729 An Easy Problem for Elfness

    An Easy Problem for Elfness Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 65535/65535 K (J ...

  2. 【HDOJ】4267 A Simple Problem with Integers

    树状数组.Easy. /* 4267 */ #include <iostream> #include <string> #include <map> #includ ...

  3. 【HDOJ】3828 A + B problem

    显然需要贪心,重叠越长越好,这样最终的串长尽可能短.需要注意的是,不要考虑中间结果,显然是个状态dp.先做预处理去重,然后求任意一对串的公共长度. /* 3828 */ #include <io ...

  4. 【HDOJ】1016 Prime Ring Problem

    经典DP,写的可能麻烦了一些. #include <stdio.h> #define false 0 #define true 1 ]; ]; ]; void DFS(int, int, ...

  5. 【HDOJ】1076 An Easy Task

    水题,如题. #include <stdio.h> #define chk(Y) (Y%4==0 && Y%100!=0) || Y%400==0 int main() { ...

  6. 【HDOJ】P2058 The sum problem

    题意很简单就是给你一个N和M,让你求在1-N的那些个子序列的值等于M 首先暴力法不解释,简单超时 再仔细想一想可以想到因为1-N是一个等差数列,可以运用我们曾经学过的只是来解决 假设开始的位置为s,结 ...

  7. HDU 4729 An Easy Problem for Elfness (主席树,树上第K大)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:给出一个带边权的图.对于每一个询问(S , ...

  8. HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Problem Description Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge wat ...

  9. HDU 4729 An Easy Problem for Elfness(树链剖分边权+二分)

    题意 链接:https://cn.vjudge.net/problem/HDU-4729 给你n个点,然你求两个点s和t之间的最大流.而且你有一定的钱k,可以进行两种操作 1.在任意连个点之间建立一个 ...

随机推荐

  1. nginx gzip filter模块分析

    API:http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/zlib-deflateinit2.html ...

  2. IOS离线教程下载与Dash的使用

    都知道,苹果官网的IOS Developer Library是开发者最喜欢用的知识仓库,但由于有时打开它实在太慢了! 但是,我们可以手动下载离线版的!离线的文档,在这里,叫做DocSet,意指文档集合 ...

  3. css3选择器二

    在HTML中,通过各种各样的属性可以给元素增加很多附加的信息,了解和掌握css3一些的选择器,是很有必要的. :enabled 和 :disabled选择器表单元素有可用(“:enabled”)和不可 ...

  4. 获取JAVA对象占用的内存大小

    介绍两种获取JAVA对象内存大小的方法. 第一种:Instrumentation 简介: 使用java.lang.instrument 的Instrumentation来获取一个对象的内存大小.利用I ...

  5. [Linux] Linux学习笔记(5)-文件与目录管理

    1.Linux目录结构为树状结构,最顶层的目录为跟目录"/",其它目录通过挂载可以将它添加到目录树中,通过解除挂载移除它们. 2.绝对路径与相对路径 绝对路径写法:由根目录&quo ...

  6. Spark Streaming揭秘 Day5 初步贯通源码

    Spark Streaming揭秘 Day5 初步贯通源码 引子 今天,让我们从Spark Streaming最重要的三个环节出发,让我们通过走读,逐步贯通源码,还记得Day1提到的三个谜团么,让我们 ...

  7. ENVI栅格文件增强后将LUT保存完输出img图像进行分类

    ENVI栅格文件储存 图像原始的DN(Digital Number)值记录图像的光谱信息,不能轻易更改。在窗口中显示的一般是经过拉伸等增强处理的LUT上的灰度值,在保存文件时,就有不同的方式。 1.  ...

  8. 【BZOJ2049】 [Sdoi2008]Cave 洞穴勘测

    Description 辉辉热衷于洞穴勘测.某天,他按照地图来到了一片被标记为JSZX的洞穴群地区.经过初步勘测,辉辉发现这片区域由n个洞穴(分别编号为1到n)以及若干通道组成,并且每条通道连接了恰好 ...

  9. crystal report format number

    ToText({#totalPrice}, 2,'.', ',')  &" €" http://crystaltricks.com/wordpress/?p=149

  10. 高仿猫眼电影选座(选票)模块-b

    上图看效果先: 1)画座位图其实不是很难一般数据都会给坐标,将坐标对应座位画出来就可以了,主要是开场动画要设置默认大小,还有座位图的数量也不是固定的,所以在初始化座位图的时侯就默认算出了整个座位图的大 ...