Problem Description
Pfctgeorge is totally a tall rich and handsome guy. He plans to build a huge water transmission network that covers the whole southwest China. To save the fund, there will be exactly one path between two cities.

Since the water every city provides and costs every day is different, he needs to transfer water from one particular city to another as much as possible in the next few days. However the pipes which connect the cities have a limited capacity for transmission. (Which means the water that transfer though the pipe should not exceed a particular amount) So he has to know the maximum water that the network can transfer in the next few days.

He thought it's a maximum flow problem, so he invites an expert in this field, Elfness (Also known as Xinhang senior sister) to help him figure it out.

Unlike Pfctgeorge, Elfness quickly finds that this problem is much easier than a normal maximum flow problem, and is willing to help Pfctgeorge.

"Oh well, this problem is not a tough one. We can ..."

Abruptly, Pfctgeorge's iPhone rings, and ... the ringtone is Mo Di Da Biao Ke.

"You can make that? Excellent! "Pfctgeorge hangs up his iPhone, and turns to Elfness.

"Here's good news for you. A construction team told me that every pipe's capacity can be extended for one day. And the price for extending one unit capacity varies from day to day. "

"Eh well, that's a good news for you, not me. Now it's rather like a minimum cost ow problem, right? But it's still not a tough one, let me have a think. "

After a few seconds' thought, Elfness comes up with a simple solution.

"Ok, we can solve it like... "

Abruptly, here comes Mo Di Da Biao Ke again.

"Seriously? You can build new pipes? Thank you very much. "

"OK, my dear Elfness, we got more good news. Another construction team said they can build one or more pipes between any two cities and their pipes are exactly like the original ones except that they only work for one day. And the capacity of the new pipes is only one, but they can be extended, too. Of course, their price to build a single pipe also varies in days. "

"You mean the new pipes can be extended too? Wow, things are getting more interesting. Give me a few minutes. "

Elfness takes out his new ultrabook which is awarded in VK cup and does some basic calculation.

"I get it. The problem can be solved ..."

Mo Di Da Biao Ke again, but this time it's from Elfness's phone.

"As you see, I have to go out. But I know someone else who can also solve this; I'll recommend this guy for you. "

And of course, that poor guy is YOU. Help Pfctgeorge solve his problem, and then the favorability about you from Elfness will raise a lot.

 
Input
The first line has a number T (T <= 10) , indicating the number of test cases.

The first line of each test case is two integers N (1 <= N <= 100000) and M (1 <= M <= 100000), indicating the number of the city that the original network connects and the number of days when Pfctgeorge needs to know about the maximum water transmissions. Then next N - 1 lines each describe a pipe that connects two cities. The format will be like U, V , cap (1 <= U, V <= N and 0 <= cap < 10000), which means the ids of the two cities the pipe connects and the transmission limit of the pipe. As is said in description, the network that the cities and pipes form is a tree (an undirected acyclic graph).

Then next M lines of the test case describe the information about the next few days. The format is like S, T, K, A, B(0 <= K <= 2^31 - 1, 1 <= A, B <= 2^31 - 1). S means the source of the water while T means the sink. K means the total budget in the day. A means the cost for a construction team to build a new pipe and B means the cost for a construction team to extend the capacity of a pipe.

I am glad to list the information of building a new pipe and extending the capacity.

1. Pfctgeorge can build a new pipe between any two cities, no matter they have been directly connected or not. Pfctgeorge can build more than one new pipe between any two cities.
2. The capacity of the pipe that was newly built is one.
3. Pfctgeorge can extend the capacity of any existed pipe including the newly built one and the original one.
4. Each time you extend the capacity of one pipe, the capacity of that pipe increases one.
5. The cost of building a new pipe is A and the cost of extending a pipe is B.
6. You can take any constructions in any times and the only limit is to make sure the total costs not exceed the budget.
7. All the work that construction team does only lasts one single day.

 
Output
For every case, you should output "Case #t:" at first, without quotes. The t is the case number starting from 1.
Then for each day, output the maximum water Pfctgeorge can transfer from S and T with a budget of K.
 
题目大意:题目好长……大概是说,给你一棵树,每条边有一个容量。然后m个询问,每个询问是互相独立的,给你两个点S T,一个预算K,建一条容量为1的新边的费用A,将某一条现有的边容量扩大1的费用B。问从S到T在预算允许的情况下最大流是多少。
思路:首先,如果扩展边,肯定在S和T之间扩展最好,若A≤B,那么直接在S和T之间建$\lfloor K / A \rfloor$条边即可,再求从A到B的最大流(怎么求等下讲)。若A>B,有两种方案。方案一,建一条S到T的边,然后扩展$\lfloor K / B \rfloor$次,求A到B最大流。方案2,在S到T的路径中扩展容量。取两个方案的最大值。
因为从S到T只有一条路,那么我们只需要知道从S到T的那条路径上,最小的边是多少,就可以求出最大流。这里可以用主席树,每个点使用父节点的历史版本(这里不介绍主席树,不懂可以去翻我以前的blog),建一棵新的线段树。然后S结点+T结点-2*LCA就可以得到S到T的线段树(LCA可以用RMQ来求,也可以像我这样用离线的tarjan),就是主席树求第1小而已。
最后的问题就是A>B的方案2,在得到S到T的线段树之后,我们最多扩展边$\lfloor K / B \rfloor$次。那么,像二分一样,在线段树上走,若可以满足小于mid的边都扩充到mid,那么往右儿子走,若不能满足,则往左儿子走,走到叶子即可。
PS:我代码中的链表是有两种用法的,一种是树上的边,另一种是tarjan用的链表。
PS:我的线段树好像有的left初始化为1有的初始化为0,但是没有WA,大概是这种题目很难搞出这么精细的WA吧……懒得改了……
 
代码(640MS):
 #include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL; const int MAXC = ;
const int MAXN = ;
const int MAXV = * ;
const int MAXE = * ; int head[MAXV], fa[MAXV];
bool vis[MAXV];
int to[MAXE], next[MAXE], weight[MAXE];
int T, n, m, ecnt; void init() {
memset(head, , sizeof(head));
memset(vis, , sizeof(vis));
for(int i = ; i <= n; ++i) fa[i] = i;
ecnt = ;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; weight[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; weight[ecnt] = c; next[ecnt] = head[v]; head[v] = ecnt++;
} struct QUERY {
int s, t, k, a, b, lca;
void read(int i) {
scanf("%d%d%d%d%d", &s, &t, &k, &a, &b);
add_edge(s + n, t + n, i);
}
} Query[MAXV]; int get_set(int x) {
return fa[x] == x ? x : fa[x] = get_set(fa[x]);
} void dfs_lca(int u, int f) {
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
dfs_lca(v, u);
fa[v] = u;
}
vis[u] = true;
for(int p = head[u + n]; p; p = next[p]) {
int v = to[p] - n;
if(vis[v]) Query[weight[p]].lca = get_set(v);
}
} struct Node {
int L, R, sum, cnt;
} tree[ * MAXN];
int root[MAXV], Tcnt; void init_Tree() {
root[] = ;
Tcnt = ;
} void insert(int &x, int left, int right, int &val) {
tree[Tcnt] = tree[x]; x = Tcnt++;
++tree[x].cnt; tree[x].sum += val;
if(left == right) return ;
int mid = (left + right) >> ;
if(val <= mid) insert(tree[x].L, left, mid, val);
else insert(tree[x].R, mid + , right, val);
} void dfs_build_tree(int u, int f, int w) {
root[u] = root[f];
if(f) insert(root[u], , MAXC, w);
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(v == f) continue;
dfs_build_tree(v, u, weight[p]);
}
} int query(int x, int y, int lca, int left, int right, int k) {
if(left == right) return left;
int t = tree[tree[x].L].cnt + tree[tree[y].L].cnt - * tree[tree[lca].L].cnt;
int mid = (left + right) >> ;
if(k <= t) return query(tree[x].L, tree[y].L, tree[lca].L, left, mid, k);
else return query(tree[x].R, tree[y].R, tree[lca].R, mid + , right, k - t);
} int query(int x, int y, int lca, int cap) {
int l = , r = MAXC, cnt = , sum = ;
while(l < r) {
int mid = (l + r) >> ;
int tmp_cnt = tree[tree[x].L].cnt + tree[tree[y].L].cnt - * tree[tree[lca].L].cnt;
int tmp_sum = tree[tree[x].L].sum + tree[tree[y].L].sum - * tree[tree[lca].L].sum;
if((cnt + tmp_cnt) * mid - (sum + tmp_sum) > cap)
x = tree[x].L, y = tree[y].L, lca = tree[lca].L, r = mid;
else x = tree[x].R, y = tree[y].R, lca = tree[lca].R, l = mid + , cnt += tmp_cnt, sum += tmp_sum;
}
return l - ;
} int main() {
scanf("%d", &T);
for(int t = ; t <= T; ++t) {
scanf("%d%d", &n, &m);
init();
for(int i = ; i < n; ++i) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
add_edge(u, v, c);
}
for(int i = ; i <= m; ++i) Query[i].read(i);
printf("Case #%d:\n", t);
dfs_lca(, );
//for(int i = 1; i <= m; ++i) printf("%d\n", Query[i].lca);
init_Tree();
dfs_build_tree(, , );
//for(int i = 1; i <= m; ++i) printf("%d\n", query(root[Query[i].s], root[Query[i].t], root[Query[i].lca], 0, MAXC, 1));
for(int i = ; i <= m; ++i) {
int ans = query(root[Query[i].s], root[Query[i].t], root[Query[i].lca], , MAXC, );
if(Query[i].a < Query[i].b) ans += Query[i].k / Query[i].a;
else {
if(Query[i].k >= Query[i].a) ans += (Query[i].k - Query[i].a) / Query[i].b + ;
ans = max(ans, query(root[Query[i].s], root[Query[i].t], root[Query[i].lca], Query[i].k / Query[i].b));
}
printf("%d\n", ans);
}
}
}

HDU 4729 An Easy Problem for Elfness(主席树)(2013 ACM/ICPC Asia Regional Chengdu Online)的更多相关文章

  1. HDU 4729 An Easy Problem for Elfness 主席树

    题意: 给出一棵树,每条边有一个容量. 有若干次询问:\(S \, T \, K \, A \, B\),求路径\(S \to T\)的最大流量. 有两种方法可以增大流量: 花费\(A\)可以新修一条 ...

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

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

  3. HDU 4735 Little Wish~ lyrical step~(DLX搜索)(2013 ACM/ICPC Asia Regional Chengdu Online)

    Description N children are living in a tree with exactly N nodes, on each node there lies either a b ...

  4. HDU 4717 The Moving Points(三分法)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description There are N points in total. Every point moves in certain direction and certain speed. W ...

  5. HDU 4722 Good Numbers(位数DP)(2013 ACM/ICPC Asia Regional Online ―― Warmup2)

    Description If we sum up every digit of a number and the result can be exactly divided by 10, we say ...

  6. HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online)

    HDU 4291 A Short problem(2012 ACM/ICPC Asia Regional Chengdu Online) 题目链接http://acm.hdu.edu.cn/showp ...

  7. HDU 5889 Barricade 【BFS+最小割 网络流】(2016 ACM/ICPC Asia Regional Qingdao Online)

    Barricade Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total S ...

  8. 数据结构(主席树):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 ...

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

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

随机推荐

  1. oracle-03 表的管理

    一.表名和列名的命名规则1).必须以字母开头2).长度不能超过30个字符3).不能使用oracle的保留字4).只能使用如下字符 a-z,a-z,0-9,$,#等 二.数据类型1).字符类char 长 ...

  2. 前端关于SEO

    提高页面加载速度. 能用css解决的不用背景图片,背景图片也尽量压缩大小,可以几个icons放在一个图片上,使用background-position找到需要的图片位置.可以减少HTTP请求数,提高网 ...

  3. 【网络流】EK算法及其优化

    今天上午我仿佛知道了什么叫做网络流,这里推荐一篇博客,大家入门网络流的可以看一下这篇博客,保证一看就懂! 博客链接: 网络流入门 这里有一篇经过我改过的EK带注释代码(博客里也有一样的,只是加了一些注 ...

  4. ABAP术语-Distribution Model

    Distribution Model 原文:http://www.cnblogs.com/qiangsheng/archive/2008/01/25/1052434.html Model that d ...

  5. ABAP术语-Application

    Application 原文:http://www.cnblogs.com/qiangsheng/archive/2007/12/15/995737.html Set of work processe ...

  6. window系统下pycharm的破解配置

    将C:\Windows\System32\drivers\etc\hosts内的写出: linux系统的话在 /etc/hosts,必须修改权限:sudo chmod a=rwx hosts 0.0. ...

  7. Mysql基础1-基础语法-字段类型

    主要: 基础 字段类型 基础 基本概念 1) 数据库分类 层次数据库,网状数据库,关系数据库 常见:SQL Server, Oracle,infomix,sybase,ibmDB2,Mysql 2)数 ...

  8. Leecode刷题之旅-C语言/python-136只出现一次的数字

    /* * @lc app=leetcode.cn id=136 lang=c * * [136] 只出现一次的数字 * * https://leetcode-cn.com/problems/singl ...

  9. 003---生成器 & 迭代器

    生成器 & 迭代器 列表生成式 现在有个需求,列表[1, 2, 3, 4, 5, 6, 7, 8, 9],将列表里的每个值加1. 二逼青年版 a = [1, 2, 3, 4, 5, 6, 7, ...

  10. 当安装mongodb客户端出现了Failed to load list of databases

    在装mongodb最新版(4.1.5开发版)服务后,我用robo3t打开它的时候遇到了这个问题. 最直接的解决办法就是换一个mongodb版本,https://github.com/Studio3T/ ...