uva 1486 Transportation (最大流+拆边)

uva 1486 Transportation

Description

There are N cities, and M directed roads connecting them. Now you want to transport K units of goods from city 1 to city N. There are many robbers on the road, so you must be very careful. The more goods you carry, the more dangerous it is. To be more specific, for each road i, there is a coefficient ai. If you want to carry x units of goods along this road, you should pay ai*x2 dollars to hire guards to protect your goods. And what’s worse, for each road i, there is an upper bound Ci, which means that you cannot transport more than Ci units of goods along this road. Please note you can only carry integral unit of goods along each road.

You should find out the minimum cost to transport all the goods safely.

Input

There are several test cases. The first line of each case contains three integers, N, M and K. (1≤N≤100, 1≤M≤5000, 0≤K≤100). Then M lines followed, each contains four integers (ui, vi, ai, Ci), indicating there is a directed road from city ui to vi, whose coefficient is ai and upper bound is Ci. (1≤ui, vi≤N, 0 < ai≤100, Ci≤5)

Output

Output one line for each test case, indicating the minimum cost. If it is impossible to transport all the K units of goods, output `-1’.

Sample Input

2 1 2

1 2 1 2

2 1 2

1 2 1 1

2 2 2

1 2 1 2

1 2 2 2

Sample Output

4

-1

3

题目大意:某国有n(n<=100)座城市,由m(m<=5000)条单向道路相连。你希望从城市1运送k(k<=100)单位货物到城市n,这些道路并不安全,有很多强盗,所以你需要雇佣镖师来做护卫。每条道路都有一个危险系数ai(ai<=100),如果你带着x个单位的货物通过,需要给镖师ai?x2的佣金,镖师才会保证你的安全。每条道路都有一个限制,最多能运送Ci(Ci<=5)的货物。现在问,在能完成运送x个单位的货物到n号城市的情况下最小的花费,如果送不到,则输出-1。

解题思路:如果不进行拆边的话,每条道路的费用是动态变化的,所以我们要进行拆边,使得每条道路的费用固定。假如一条边的危险系数是a,最多能运送的货物为C,那么这条边就可以C条边每条边的费用为a?(i2?(i?1)2),i从1到C,容量为1。这样拆出来的边总费用为a?C2,总容量为C。拆完边,建完图,跑一发最小费。

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <queue>
using namespace std;

const int INF = 0x3f3f3f3f;
const int N = 200;
const int M = 150000;
typedef long long ll;
int n, m, k, s, t;
int pre[N], inq[N];
ll a[N], d[N];
struct Edge{
    int from, to;
    ll cap, flow;
    ll cos;
};

vector<Edge> edges;
vector<int> G[M];

void init() {
    for (int i = 0; i < M; i++) G[i].clear();
    edges.clear();
}

void addEdge(int from, int to, ll cap, ll flow, ll cos) {
    edges.push_back((Edge){from, to, cap, 0, cos});
    edges.push_back((Edge){to, from, 0, 0, -cos});
    int m = edges.size();
    G[from].push_back(m - 2); G[to].push_back(m - 1);
}

int BF(int s, int t, ll& flow, ll& cost) {
    queue<int> Q;
    memset(inq, 0, sizeof(inq));
    memset(a, 0, sizeof(a));
    memset(pre, 0, sizeof(pre));
    for (int i = 0; i < N; i++) d[i] = INF;
    d[s] = 0;
    a[s] = INF;
    inq[s] = 1;
    int flag = 1;
    pre[s] = 0;
    Q.push(s);
    while (!Q.empty()) {
        int u = Q.front(); Q.pop();
        inq[u] = 0;
        for (int i = 0; i < G[u].size(); i++) {
            Edge &e = edges[G[u][i]];
            if (e.cap > e.flow && d[e.to] > d[u] + e.cos) {
                d[e.to] = d[u] + e.cos;
                a[e.to] = min(a[u], e.cap - e.flow);
                pre[e.to] = G[u][i];
                if (!inq[e.to]) {
                    inq[e.to] = 1;
                    Q.push(e.to);
                }
            }
        }
        flag = 0;
    }
    if (d[t] == INF) return 0;
    flow += a[t];
    cost += (ll)d[t] * (ll)a[t];
    for (int u = t; u != s; u = edges[pre[u]].from) {
        edges[pre[u]].flow += a[t];
        edges[pre[u]^1].flow -= a[t];
    }
    return 1;
}

int MCMF(int s, int t, ll& cost) {
    ll flow = 0;
    cost = 0;
    while (BF(s, t, flow, cost));
    return flow;
}

void input() {
    int u, v;
    ll a;
    ll c;
    for (int i = 0; i < m; i++) {
        scanf("%d %d %lld %lld", &u, &v, &a, &c);
        for (int i = 1; i <= c; i++) {
            addEdge(u, v, 1, 0, a * (i * i - (i - 1) * (i - 1)));
        }
    }
    addEdge(0, 1, k, 0, 0);
    s = 0, t = n;
}

int main() {
    while (scanf("%d %d %d", &n, &m, &k) == 3) {
        init();
        input();
        ll cost;
        if (MCMF(s, t, cost) != k) printf("-1\n");
        else printf("%lld\n", cost);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许也可以转载,不过要注明出处哦。

时间: 2024-08-25 13:23:45

uva 1486 Transportation (最大流+拆边)的相关文章

UVA 1486 - Transportation(网络流+拆边)

UVA 1486 - Transportation 题目链接 题意:一个有向图上运输k货物,有一些边,每个边一个系数a,经过该边如果有x货物,就要缴纳a x x的钱,问运输从1到n最小的代价 思路:费用流,这题边的容量c最大只有5,所以可以拆边,一条边拆成c条边,每条容量1,对应相应的代价为a * (i^2 - (i - 1)^2),然后跑一下费用流即可 代码: #include <cstdio> #include <cstring> #include <vector>

uva 301 Transportation(回溯)

uva 301 Transportation Ruratania is just entering capitalism and is establishing new enterprising activities in many fields including transport. The transportation company TransRuratania is starting a new express train from city A to city B with seve

HDU 3667 费用流 拆边 Transportation

题意: 有N个城市,M条有向道路,要从1号城市运送K个货物到N号城市. 每条有向道路<u, v>运送费用和运送量的平方成正比,系数为ai 而且每条路最多运送Ci个货物,求最小费用. 分析: 拆边,每条边拆成费用为a, 3a, 5a的边,这样就能保证每条边的费用和流量的平方成正比. 因为最多运送K个货物,所以增加一个源点和城市1连一条容量为K费用为0的边. 跑一边最小费用最大流,如果满流才有解. 1 #include <iostream> 2 #include <cstdio&

hdu 3667(最小费用最大流+拆边)

Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2670    Accepted Submission(s): 1157 Problem Description There are N cities, and M directed roads connecting them. Now you want to

zoj3231 Apple Transportation(最大流)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Apple Transportation Time Limit: 1 Second      Memory Limit: 32768 KB There's a big apple tree in the forest. In the tree there are N nodes (numbered from 0 to N - 1), and the nodes are conne

UVA 563 Crimewave (最大流,拆点)

http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=504  Crimewave  Nieuw Knollendam is a very modern town. This becomes clear already when looking at the layout of its map, which is just a rectangula

HDU 3667-- Transportation【最小费最大流 &amp;&amp; 拆边建图 &amp;&amp; 经典】

Transportation Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2441    Accepted Submission(s): 1041 Problem Description There are N cities, and M directed roads connecting them. Now you want to

UVALive-5095 Transportation (最小费用流+拆边)

题目大意:有n个点,m条单向边.要运k单位货物从1到n,但是每条道路上都有一个参数ai,表示经这条路运送x个单位货物需要花费ai*x*x个单位的钱.求最小费用. 题目分析:拆边.例如:u到v的容量为5,则拆成容量均为1,单位费用分别为1,3,5,7,9的5条边.求流恰好能满足运输需求时的最小费用即可. 代码如下: # include<iostream> # include<cstdio> # include<cmath> # include<string>

UVA 10779 (最大流)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=33631 题目大意:Bob有一些贴纸,他可以和别人交换,他可以把自己独有的贴纸拿出去,也可以把重复的贴纸拿出去(有时候把独有的贴纸而不是重复的贴纸拿出去能换到更多贴纸). Bob的朋友也有一些贴纸,但是他们只会拿自己重复的贴纸和Bob换,而且换的是自己没有的贴纸. 求Bob最后最多能有多少种贴纸. 解题思路: 题目意思很明确了.就算把重复的贴纸拿出去也不一定最优,贪