• HDU 3947 River Problem


    River Problem

    Time Limit: 2000ms
    Memory 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 of test 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 a number 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

     
    解题:费用流,哎,好难,由不等式造费用流,一下子吃不消
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 using PII = pair<int,int>;
     4 const int INF = ~0u>>2;
     5 const int maxn = 10010;
     6 struct arc {
     7     int to,flow,cost,next;
     8     arc(int x = 0,int y = 0,int z = 0,int nxt = -1) {
     9         to = x;
    10         flow = y;
    11         cost = z;
    12         next = nxt;
    13     }
    14 } e[1000005];
    15 int head[maxn],d[maxn],p[maxn],id[maxn],tot,S = 0,T,flow;
    16 bool in[maxn] = {};
    17 vector<PII>g[maxn];
    18 void add(int u,int v,int flow,int cost) {
    19     e[tot] = arc(v,flow,cost,head[u]);
    20     head[u] = tot++;
    21     e[tot] = arc(u,0,-cost,head[v]);
    22     head[v] = tot++;
    23 }
    24 bool spfa() {
    25     queue<int>q;
    26     memset(d,0x3f,sizeof d);
    27     memset(p,-1,sizeof p);
    28     d[S] = 0;
    29     q.push(S);
    30     while(!q.empty()) {
    31         int u = q.front();
    32         q.pop();
    33         in[u] = false;
    34         for(int i = head[u]; ~i; i = e[i].next) {
    35             if(e[i].flow && d[e[i].to] > d[u] + e[i].cost) {
    36                 d[e[i].to] = d[u] + e[i].cost;
    37                 p[e[i].to] = i;
    38                 if(!in[e[i].to]) {
    39                     in[e[i].to] = true;
    40                     q.push(e[i].to);
    41                 }
    42             }
    43         }
    44     }
    45     return p[T] > -1;
    46 }
    47 PII solve() {
    48     int flow = 0,cost = 0;
    49     while(spfa()) {
    50         int minF = INF;
    51         for(int i = p[T]; ~i; i = p[e[i^1].to])
    52             minF = min(minF,e[i].flow);
    53         for(int i = p[T]; ~i; i = p[e[i^1].to]) {
    54             e[i].flow -= minF;
    55             e[i^1].flow += minF;
    56         }
    57         cost += minF*d[T];
    58         flow += minF;
    59     }
    60     return {flow,cost};
    61 }
    62 void dfs(int u,int psum) {
    63     int sum = 0;
    64     for(int i = g[u].size()-1; i >= 0; --i) {
    65         dfs(g[u][i].first,g[u][i].second);
    66         sum += g[u][i].second;
    67         add(id[u],id[g[u][i].first],INF,0);
    68     }
    69     int tmp = psum - sum;
    70     if(tmp > 0) {
    71         flow += tmp;
    72         add(S,id[u],tmp,0);
    73     } else if(tmp < 0) add(id[u],T,-tmp,0);
    74 }
    75 int main() {
    76     int kase,cs = 1,n,m,u,v,w,L,C;
    77     scanf("%d",&kase);
    78     while(kase--) {
    79         scanf("%d",&n);
    80         for(int i = tot = flow = 0; i <= n; ++i) g[i].clear();
    81         for(int i = 1; i < n; ++i) {
    82             scanf("%d%d%d",&u,&v,&w);
    83             g[v].push_back(PII(u,w));
    84             id[u] = i;
    85         }
    86         id[1] = n;
    87         memset(head,-1,sizeof head);
    88         g[T = n + 1].push_back(PII(1,0));
    89         dfs(1,0);
    90         scanf("%d",&m);
    91         while(m--) {
    92             scanf("%d%d%d%d",&u,&v,&L,&C);
    93             add(id[u],id[v],L,C);
    94         }
    95         PII ret = solve();
    96         printf("Case #%d: %d
    ",cs++,ret.first == flow?ret.second:-1);
    97     }
    98     return 0;
    99 }
    View Code
  • 相关阅读:
    oracle一些常用的单记录函数
    javascript闭包(closure)
    【Matlab开发】matlab中bar绘图设置与各种距离度量
    【Matlab开发】matlab中bar绘图设置与各种距离度量
    【Matlab开发】matlab中norm范数以及向量点积、绘图设置相关
    【Matlab开发】matlab中norm范数以及向量点积、绘图设置相关
    【编程开发】opencv实现对Mat中某一列或某一行的元素进行normalization
    【编程开发】opencv实现对Mat中某一列或某一行的元素进行normalization
    【编程开发】C语言中随机数rand使用注意事项
    【编程开发】C语言中随机数rand使用注意事项
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4972663.html
Copyright © 2020-2023  润新知