HDU 3947 River Problem
2015-11-17 19:41
351 查看
River Problem
Time Limit: 2000msMemory Limit: 65536KB
This problem will be judged on HDU. Original ID: 3947
64-bit integer IO format: %I64d Java class name: Main
The River of Bitland is now heavily polluted. To solve this problem, the King of Bitland decides to use some kinds of chemicals to make the river clean again.
The structure of the river contains n nodes
and exactly n-1 edges between those nodes. It's just the same as all the
rivers in this world: The edges are all unidirectional to represent
water flows. There are source points, from which the water flows, and
there is exactly one sink node, at which all parts of the river meet
together and run into the sea. The water always flows from sources to
sink, so from any nodes we can find a directed path that leads to the
sink node. Note that the sink node is always labeled 1.
As you
can see, some parts of the river are polluted, and we set a weight Wi
for each edge to show how heavily polluted this edge is. We have m kinds
of chemicals to clean the river. The i-th chemical can decrease the
weight for all edges in the path from Ui to Vi by exactly 1. Moreover,
we can use this kind of chemical for Li times, the cost for each time is
Ci. Note that you can still use the chemical even if the weight of
edges are 0, but the weight of that edge will not decrease this time.
When the weight of all edges are 0, the river is cleaned, please help us to clean the river with the least cost.
Input
The first line of the input is an integer T representing the number oftest cases. The following T blocks each represents a test case.
The
first line of each block contains a number n (2<=n<=150)
representing the number of nodes. The following n-1 lines each contains 3
numbers U, V, and W, means there is a directed edge from U to V, and
the pollution weight of this edge is W. (1<=U,V<=n,
0<=W<=20)
Then follows an number m (1<=m<=2000),
representing the number of chemical kinds. The following m lines each
contains 4 numbers Ui, Vi, Li and Ci (1<=Ui,Vi<=n,
1<=Li<=20, 1<=Ci<=1000), describing a kind of chemical, as
described above. It is guaranteed that from Ui we can always find a
directed path to Vi.
Output
First output "Case #k: ", where k is the case numbers, then follows anumber indicating the least cost you are required to calculate, if the
answer does not exist, output "-1" instead.
Sample Input
2 3 2 1 2 3 1 1 1 3 1 2 2 3 2 1 2 3 1 1 2 3 1 2 2 2 1 2 1
Sample Output
Case #1: -1 Case #2: 4
Source
2011 Multi-University Training Contest 11 - Host by UESTC解题:费用流,哎,好难,由不等式造费用流,一下子吃不消
#include <bits/stdc++.h> using namespace std; using PII = pair<int,int>; const int INF = ~0u>>2; const int maxn = 10010; struct arc { int to,flow,cost,next; arc(int x = 0,int y = 0,int z = 0,int nxt = -1) { to = x; flow = y; cost = z; next = nxt; } } e[1000005]; int head[maxn],d[maxn],p[maxn],id[maxn],tot,S = 0,T,flow; bool in[maxn] = {}; vector<PII>g[maxn]; void add(int u,int v,int flow,int cost) { e[tot] = arc(v,flow,cost,head[u]); head[u] = tot++; e[tot] = arc(u,0,-cost,head[v]); head[v] = tot++; } bool spfa() { queue<int>q; memset(d,0x3f,sizeof d); memset(p,-1,sizeof p); d[S] = 0; q.push(S); while(!q.empty()) { int u = q.front(); q.pop(); in[u] = false; for(int i = head[u]; ~i; i = e[i].next) { if(e[i].flow && d[e[i].to] > d[u] + e[i].cost) { d[e[i].to] = d[u] + e[i].cost; p[e[i].to] = i; if(!in[e[i].to]) { in[e[i].to] = true; q.push(e[i].to); } } } } return p[T] > -1; } PII solve() { int flow = 0,cost = 0; while(spfa()) { int minF = INF; for(int i = p[T]; ~i; i = p[e[i^1].to]) minF = min(minF,e[i].flow); for(int i = p[T]; ~i; i = p[e[i^1].to]) { e[i].flow -= minF; e[i^1].flow += minF; } cost += minF*d[T]; flow += minF; } return {flow,cost}; } void dfs(int u,int psum) { int sum = 0; for(int i = g[u].size()-1; i >= 0; --i) { dfs(g[u][i].first,g[u][i].second); sum += g[u][i].second; add(id[u],id[g[u][i].first],INF,0); } int tmp = psum - sum; if(tmp > 0) { flow += tmp; add(S,id[u],tmp,0); } else if(tmp < 0) add(id[u],T,-tmp,0); } int main() { int kase,cs = 1,n,m,u,v,w,L,C; scanf("%d",&kase); while(kase--) { scanf("%d",&n); for(int i = tot = flow = 0; i <= n; ++i) g[i].clear(); for(int i = 1; i < n; ++i) { scanf("%d%d%d",&u,&v,&w); g[v].push_back(PII(u,w)); id[u] = i; } id[1] = n; memset(head,-1,sizeof head); g[T = n + 1].push_back(PII(1,0)); dfs(1,0); scanf("%d",&m); while(m--) { scanf("%d%d%d%d",&u,&v,&L,&C); add(id[u],id[v],L,C); } PII ret = solve(); printf("Case #%d: %d\n",cs++,ret.first == flow?ret.second:-1); } return 0; }
View Code
相关文章推荐
- 给定一篇英文文章,找出其中使用频率最高的英语单词。
- 回溯法-旅行售货员问题(C语言)
- TapGestureRecognizer的简单介绍
- LeetCode OJ:Ugly Number II(丑数II)
- servlet 的当前路径
- 操作系统的IO管理介绍
- Unity Application.persistentDataPath 空值
- js字符串的方法
- swift中fallthrough的作用
- excel将列序号改为数字
- CSS中float属性详解
- 八皇后问题的分析与解法
- 通过后台控制前台页面输出,弹窗时出现乱码
- POJ2251 Dungeon Master(3D迷宫 bfs)
- 基础知识系列6--八大排序(未写完)
- java_XML_DOM1
- codemirror覆盖默认按键事件
- e代驾狂野裁员 O2O逐渐恢复理智?
- C语言基础-- 内存存储
- Angular directive 递归渲染