CSU 1506: Double Shortest Paths(最小费用最大流)

来源:互联网 发布:天津mac专柜 编辑:程序博客网 时间:2024/05/16 15:38

题目链接:http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1506


Description

Input

There will be at most 200 test cases. Each case begins with two integers n, m (1<=n<=500, 1<=m<=2000), the number of caves and passages. Each of the following m lines contains four integers u, v, di and ai (1<=u,v<=n, 1<=di<=1000, 0<=ai<=1000). Note that there can be multiple passages connecting the same pair of caves, and even passages connecting a cave and itself.

Output

For each test case, print the case number and the minimal total difficulty.

Sample Input

4 41 2 5 12 4 6 01 3 4 03 4 9 14 41 2 5 102 4 6 101 3 4 103 4 9 10

Sample Output

Case 1: 23Case 2: 24

HINT

Source

湖南省第十届大学生计算机程序设计竞赛


题意:

有两个人;

给出路径之间第一个人走所需要的费用和第二个人走所需要的费用(在第一个人所需的 费用上再加上第二次的费用);

求两个人一共所需要的最小费用!

代码如下:(套用kuangbin模板)

#include <cstdio>#include <cstring>#include <algorithm>#include <queue>using namespace std;//点的总数为 N,点的编号 1~Nconst int MAXN = 10000;const int MAXM = 100000;const int INF = 0x3f3f3f3f;struct Edge{    int to, next, cap, flow, cost;} edge[MAXM];int head[MAXN],tol;int pre[MAXN],dis[MAXN];bool vis[MAXN];int N, M;void init(int n){    N = n;    tol = 0;    memset(head, -1, sizeof(head));}void addedge(int u, int v, int cap, int cost){    edge[tol]. to = v;    edge[tol]. cap = cap;    edge[tol]. cost = cost;    edge[tol]. flow = 0;    edge[tol]. next = head[u];    head[u] = tol++;    edge[tol]. to = u;    edge[tol]. cap = 0;    edge[tol]. cost = -cost;    edge[tol]. flow = 0;    edge[tol]. next = head[v];    head[v] = tol++;}bool spfa(int s, int t){    queue<int>q;    for(int i = 0; i < N; i++)    {        dis[i] = INF;        vis[i] = false;        pre[i] = -1;    }    dis[s] = 0;    vis[s] = true;    q.push(s);    while(!q.empty())    {        int u = q.front();        q.pop();        vis[u] = false;        for(int i = head[u]; i != -1; i = edge[i]. next)        {            int v = edge[i]. to;            if(edge[i]. cap > edge[i]. flow &&                    dis[v] > dis[u] + edge[i]. cost )            {                dis[v] = dis[u] + edge[i]. cost;                pre[v] = i;                if(!vis[v])                {                    vis[v] = true;                    q.push(v);                }            }        }    }    if(pre[t] == -1) return false;    else return true;}//返回的是最大流, cost存的是最小费用int minCostMaxflow(int s, int t, int &cost){    int flow = 0;    cost = 0;    while(spfa(s,t))    {        int Min = INF;        for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to])        {            if(Min > edge[i]. cap - edge[i]. flow)                Min = edge[i]. cap - edge[i]. flow;        }        for(int i = pre[t]; i != -1; i = pre[edge[i^1]. to])        {            edge[i]. flow += Min;            edge[i^1]. flow -= Min;            cost += edge[i]. cost * Min;        }        flow += Min;    }    return flow;}int main(){    int n, m;    int u, v, cost1, cost2;    int cas = 0;    while(~scanf("%d%d",&n,&m))    {        init(n+2);//注意        for(int i = 0; i < m; i++)        {            scanf("%d%d%d%d",&u,&v,&cost1,&cost2);            addedge(u,v,1,cost1);//流量为1            addedge(u,v,1,cost1+cost2);        }        //添加一个总的起点,一个终点,使编号从0~n        addedge(0,1,2,0);//流量为2,费用为0        addedge(n,n+1,2,0);        int ans = 0;        minCostMaxflow(0,n+1,ans);        printf("Case %d: %d\n",++cas,ans);    }    return 0;}


1 0
原创粉丝点击