Problem Description

瑶瑶(tsyao)是某知名货运公司(顺丰)的老板,这个公司很大,货物运输量极大,因此公司修建了许多交通设施,掌控了一个国家的交通运输。

这个国家有n座城市,公司的总部在1号城市。

公司下管辖的有m条道路和n-1段火车线路。

这m条道路和n-1条火车线路都可以用u来表示起点,v来表示终点(数据保证m条道路和n-1条火车线路构成有向无环图)。

这n-1段火车道保证从1号城市出发,能够有唯一的一道只包含火车道的线路到达其他n-1座城市。

每条道路和每段火车道都有一个最佳搭载货物值ai,如果要搭载的货物超过了ai,公司需要对经过该路线的超过ai的每单位货物增加bi的维修费用,由于种种原因,如果搭载的货物低于ai,公司需要对少的每单位货物(设该路线有x的货物,则计算为ai-x单位)增加ci的维修费用。当然,每单位货物经过时,会有di的基础维护费用。

这里有两种操作:

C xi yi zi: 随着时间和环境的变化,火车道会受到一些影响,xi到yi的火车道ai会改变zi(新的ai应该为ai+zi),若xi不能到达yi,则将hi到xi和hi到yi的路段ai改变zi(hi为可以到达xi和yi的城市,且不存在fi使得  hi能够到达fi,fi能够到达xi和yi)。

当某火车道的ai值小于0时,我们看做该条火车道的最佳搭载货物值为0(当然ai事实上是负数);

Q vi wi: 查询当计划将wi单位货物从1号城市到vi号城市时,该公司需要的最小维护费用。维护费用计算为每条道路和火车道的维护费用的和(SUMbi+SUMci+SUMdi)。

Input

第一行两个整数n,m,用空格隔开。

接下来n-1+m行,每行u,v,ai,bi,ci,di六个整数。

前n-1行表示火车线路,后m行表示道路。

接下来一行为一个整数q。

接下来q行分别为上述两种操作。

Output

对于每次Q操作,输出答案,数据保证答案在int范围内。

题目大意:略。

思路:

——————————————————————————————————————————————————————————————————

扒官方题解:http://tsyao.tk/archives/94

对付修改的话,就用树链剖分就好,然后每次询问跑网络流。

网络流这样建图,先假设我每条边都跑了0的流量,我们先算出跑了0的流量的费用,然后对于一条边,我跑了小于ai的流量的时候,每次增加一点流量,就相当于减小了ci的费用,所以把一条边拆成两条边,一条是费用为-ci+di,上界为ai的边,一条是费用为bi+di,上界为无穷的边。。。

——————————————————————————————————————————————————————————————————

PS:简单的说就是两条SB题合在一起出,这样也脱离不了它是SB题的结果。但是却忘了删一条调试语句导致无限TLE……

代码(1772MS):

 #include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std;
typedef long long LL; const int MAXN = ;
const int MAXV = MAXN;
const int MAXE = * ( * + MAXN * );
const int MAXT = MAXN << ;
const int INF = 0x3f3f3f3f; struct SPFA_COST_FLOW {
int head[MAXV];
int to[MAXE], next[MAXE], cap[MAXE], flow[MAXE];
LL cost[MAXE];
int n, m, ecnt, st, ed; void init(int n) {
this->n = n;
memset(head + , -, n * sizeof(int));
ecnt = ;
} void add_edge(int u, int v, int f, LL c) {
to[ecnt] = v; cap[ecnt] = f; cost[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; cap[ecnt] = ; cost[ecnt] = -c; next[ecnt] = head[v]; head[v] = ecnt++;
} void clear() {
memset(flow, , ecnt * sizeof(int));
} LL dis[MAXV];
int pre[MAXV];
bool vis[MAXV]; bool spfa() {
memset(vis + , , n * sizeof(bool));
memset(dis, 0x3f, (n + ) * sizeof(LL));
queue<int> que; que.push(st);
dis[st] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = false;
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(cap[p] - flow[p] && dis[u] + cost[p] < dis[v]) {
dis[v] = dis[u] + cost[p];
pre[v] = p;
if(!vis[v]) {
que.push(v);
vis[v] = true;
}
}
}
}
return dis[ed] < dis[];
} LL maxFlow, minCost; LL min_cost_flow(int ss, int tt) {
st = ss, ed = tt;
maxFlow = minCost = ;
while(spfa()) {
int u = ed, tmp = INF;
while(u != st) {
tmp = min(tmp, cap[pre[u]] - flow[pre[u]]);
u = to[pre[u] ^ ];
}
u = ed;
while(u != st) {
flow[pre[u]] += tmp;
flow[pre[u] ^ ] -= tmp;
u = to[pre[u] ^ ];
}
maxFlow += tmp;
minCost += tmp * dis[ed];
}
return minCost;
}
} G; struct Tree {
struct Edge {
int a, b, c, d, u, v;
void read() {
scanf("%d%d%d%d%d%d", &u, &v, &a, &b, &c, &d);
}
} tree[MAXN], edge[MAXE];
int tid[MAXN], eid[MAXN], size[MAXN], son[MAXN], top[MAXN], dep[MAXN], fa[MAXN];
int n, m, q; int head[MAXV], pre[MAXV], ecnt, dfs_clock;
int to[MAXE], next[MAXE], id[MAXE];
LL add[MAXT]; void init() {
memset(head + , -, n * sizeof(int));
ecnt = dfs_clock = ;
} void add_edge(int u, int v, int i) {
to[ecnt] = v; id[ecnt] = i; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; id[ecnt] = i; next[ecnt] = head[v]; head[v] = ecnt++;
} void dfs_size(int u, int f, int depth) {
size[u] = ; dep[u] = depth; fa[u] = f;
int maxsize = son[u] = ;
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(v == f) continue;
pre[v] = p;
dfs_size(v, u, depth + );
size[u] += size[v];
if(size[v] > maxsize) {
maxsize = size[v];
son[u] = v;
}
}
} void dfs_heavy_edge(int u, int ancestor) {
tid[u] = ++dfs_clock; eid[dfs_clock] = id[pre[u]];
top[u] = ancestor;
if(son[u]) dfs_heavy_edge(son[u], ancestor);
for(int p = head[u]; ~p; p = next[p]) {
int v = to[p];
if(v == fa[u] || v == son[u]) continue;
dfs_heavy_edge(v, v);
}
} #define ll (x << 1)
#define rr (ll | 1)
#define mid ((l + r) >> 1) void pushdown(int x) {
if(add[x]) {
add[ll] += add[x];
add[rr] += add[x];
add[x] = ;
}
} void pushadd(int x, int l, int r) {
if(l == r) {
if(l > ) tree[eid[l]].a += add[x];
add[x] = ;
} else {
pushdown(x);
pushadd(ll, l, mid);
pushadd(rr, mid + , r);
}
} void modify(int x, int l, int r, int a, int b, int val) {
if(a <= l && r <= b) {
add[x] += val;
} else {
if(a <= mid) modify(ll, l, mid, a, b, val);
if(mid < b) modify(rr, mid + , r, a, b, val);
}
} void modify(int x, int y, int val) {
while(top[x] != top[y]) {
if(dep[top[x]] < dep[top[y]]) swap(x, y);
modify(, , n, tid[top[x]], tid[x], val);
x = fa[top[x]];
}
if(x != y) {
if(dep[x] < dep[y]) swap(x, y);
modify(, , n, tid[son[y]], tid[x], val);
}
} int gid[MAXV];
void initQuery() {
G.init(n + );
for(int i = ; i < n; ++i) {
Edge &t = tree[i];
gid[i] = G.ecnt;
G.add_edge(t.u, t.v, max(, t.a), t.d - t.c);
G.add_edge(t.u, t.v, INF, t.d + t.b);
}
for(int i = ; i < m; ++i) {
Edge &t = edge[i];
G.add_edge(t.u, t.v, max(, t.a), t.d - t.c);
G.add_edge(t.u, t.v, INF, t.d + t.b);
}
G.add_edge(n + , , , );
} int query(int tt, int val) {
int ss = n + ;
pushadd(, , n);
LL sum = ;
for(int i = ; i < n; ++i) {
Edge &t = tree[i];
sum += t.c * max(, t.a);
G.cap[gid[i]] = max(, t.a);
}
for(int i = ; i < m; ++i) {
Edge &t = edge[i];
sum += t.c * max(, t.a);
}
G.cap[G.ecnt - ] = val;
G.clear();
return sum + G.min_cost_flow(ss, tt);
} void work() {
scanf("%d%d", &n, &m);
for(int i = ; i < n; ++i) tree[i].read();
for(int i = ; i < m; ++i) edge[i].read();
init();
initQuery();
for(int i = ; i < n; ++i) add_edge(tree[i].u, tree[i].v, i);
dfs_size(, , );
dfs_heavy_edge(, );
scanf("%d", &q);
char op;
for(int i = , a, b, c; i < q; ++i) {
scanf(" %c", &op);
if(op == 'Q') {
scanf("%d%d", &a, &b);
printf("%d\n", query(a, b));
} else {
scanf("%d%d%d", &a, &b, &c);
modify(a, b, c);
}
}
}
} T; int main() {
T.work();
}

ACdream 1103 瑶瑶正式成为CEO(树链剖分+费用流)的更多相关文章

  1. BZOJ 1103: [POI2007]大都市meg( 树链剖分 )

    早上数学考挂了...欲哭无泪啊下午去写半个小时政治然后就又可以来刷题了.. 树链剖分 , 为什么跑得这么慢... ------------------------------------------- ...

  2. 1103. [POI2007]MEG-Megalopolis【树链剖分】

    Description 在经济全球化浪潮的影响下,习惯于漫步在清晨的乡间小路的邮递员Blue Mary也开始骑着摩托车传递邮件了. 不过,她经常回忆起以前在乡间漫步的情景.昔日,乡下有依次编号为1.. ...

  3. HDU 5452——Minimum Cut——————【树链剖分+差分前缀和】ACdream 1429——Diversion——————【树链剖分】

    Minimum Cut Time Limit: 3000/2000 MS (Java/Others)    Memory Limit: 65535/102400 K (Java/Others)Tota ...

  4. BZOJ 2157: 旅游( 树链剖分 )

    树链剖分.. 样例太大了根本没法调...顺便把数据生成器放上来 -------------------------------------------------------------------- ...

  5. BZOJ 3626: [LNOI2014]LCA [树链剖分 离线|主席树]

    3626: [LNOI2014]LCA Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 2050  Solved: 817[Submit][Status ...

  6. BZOJ 1984: 月下“毛景树” [树链剖分 边权]

    1984: 月下“毛景树” Time Limit: 20 Sec  Memory Limit: 64 MBSubmit: 1728  Solved: 531[Submit][Status][Discu ...

  7. codevs 1228 苹果树 树链剖分讲解

    题目:codevs 1228 苹果树 链接:http://codevs.cn/problem/1228/ 看了这么多树链剖分的解释,几个小时后总算把树链剖分弄懂了. 树链剖分的功能:快速修改,查询树上 ...

  8. 并查集+树链剖分+线段树 HDOJ 5458 Stability(稳定性)

    题目链接 题意: 有n个点m条边的无向图,有环还有重边,a到b的稳定性的定义是有多少条边,单独删去会使a和b不连通.有两种操作: 1. 删去a到b的一条边 2. 询问a到b的稳定性 思路: 首先删边考 ...

  9. 树链剖分+线段树 CF 593D Happy Tree Party(快乐树聚会)

    题目链接 题意: 有n个点的一棵树,两种操作: 1. a到b的路径上,给一个y,对于路径上每一条边,进行操作,问最后的y: 2. 修改某个条边p的值为c 思路: 链上操作的问题,想树链剖分和LCT,对 ...

随机推荐

  1. sqlserver 简单的事物用法

    SELECT * FROM Interface_UserPort BEGIN TRY BEGIN TRAN Tran_2012_12_25 ,) --raiserror 50005N'抛出错误' CO ...

  2. gogs安装

    1.下载gogs文件,如果图方便可以选择编译好的文件网址https://gogs.io/docs/installation/install_from_binary 2.gogs web运行gogs 3 ...

  3. Qt 之 去除窗口部件被选中后的焦点虚线框(设置Qt::NoFocus即可)

    http://blog.csdn.net/goforwardtostep/article/details/53420529

  4. C#中集合汇总

    平时敲代码,只关注如何使用,没有深入去研究一些本质性的东西,靠死记硬背,不去真正理解,其实最后是很难记住的. 对于C#常见的集合,自己平时好像只有用到List,Dictionary,ArrayList ...

  5. Magento添加一个下拉登陆菜单Create Magento Dropdown Login in a few minutes

    Dropdown login forms are not a feature many online stores use, but in some cases they could be quite ...

  6. Top Five Communication Skills for Project Managers

    Research among project managers globally identifies top communication skills for leading teams. Lead ...

  7. 【转】Android性能优化之布局优化篇

     转自:http://blog.csdn.net/feiduclear_up/article/details/46670433 Android性能优化之布局优化篇 分类: andorid 开发2015 ...

  8. shell 判断字符串是否为数字

    本篇文章主要介绍了"shell 判断字符串是否为数字",主要涉及到shell 判断字符串是否为数字方面的内容,对于shell 判断字符串是否为数字感兴趣的同学可以参考一下. #!/ ...

  9. [SharpDevelop]菜单状态更新

    方式一 在Idle方法中更新 void OnApplicationIdle(object sender, EventArgs e) { // Use the Idle event to update ...

  10. ORA-28056:Writing audit records to Windows EventLog failed的问题

    右键“我的电脑”--‘管理’--事件查看器--点击左边的日志(应用程序日志.安全日志.系统日志),右击某个项目,选择‘清除所有事件'即可删除.