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

题意:2个人从1走到n,假设一条路第一次走则是价值di,假设第二次还走这条路则须要价值di+ai,要你输出2个人到达终点的最小价值!

太水了!一条边建2次就OK了。第一次价值为di,第二次为ai+di,加入源点汇点跑最小费用最大流就OK了!

AC代码:

#include<iostream>
#include<string>
#include<algorithm>
#include<cstdlib>
#include<cstdio>
#include<set>
#include<map>
#include<vector>
#include<cstring>
#include<stack>
#include<cmath>
#include<queue>
using namespace std;
#define CL(x,v); memset(x,v,sizeof(x));
#define INF 0x3f3f3f3f
#define LL long long
#define REP(i,r,n) for(int i=r;i<=n;i++)
#define RREP(i,n,r) for(int i=n;i>=r;i--)

int sumFlow;
const int MAXN = 600+10;
const int MAXM = 4000+10;
struct Edge
{
    int u, v, cap, cost;
    int next;
}edge[MAXM<<2];

int NE;
int head[MAXN], dist[MAXN], pp[MAXN];
bool vis[MAXN];

void init()
{
    NE = 0;
    memset(head, -1, sizeof(head));
}
void addedge(int u, int v, int cap, int cost)
{
    edge[NE].u = u;
    edge[NE].v = v;
    edge[NE].cap = cap;
    edge[NE].cost = cost;
    edge[NE].next = head[u];
    head[u] = NE++;

    edge[NE].u = v;
    edge[NE].v = u;
    edge[NE].cap = 0;
    edge[NE].cost = -cost;
    edge[NE].next = head[v];
    head[v] = NE++;
}
bool SPFA(int s, int t, int n)
{
    int i, u, v;
    queue <int> qu;
    memset(vis,false,sizeof(vis));
    memset(pp,-1,sizeof(pp));
    for(i = 0; i <= n; i++) dist[i] = INF;
    vis[s] = true; dist[s] = 0;
    qu.push(s);
    while(!qu.empty())
    {
        u = qu.front(); qu.pop(); vis[u] = false;
        for(i = head[u]; i != -1; i = edge[i].next)
        {
            v = edge[i].v;
            if(edge[i].cap && dist[v] > dist[u] + edge[i].cost)
            {
                dist[v] = dist[u] + edge[i].cost;
                pp[v] = i;
                if(!vis[v])
                {
                    qu.push(v);
                    vis[v] = true;
                }
            }
        }
    }
    if(dist[t] == INF) return false;
    return true;
}
int MCMF(int s, int t, int n)
{
    int flow = 0;
    int i, minflow, mincost;
    mincost = 0;
    while(SPFA(s, t, n))
    {
        minflow = INF + 1;
        for(i = pp[t]; i != -1; i = pp[edge[i].u])
            if(edge[i].cap < minflow)
                minflow = edge[i].cap;
        flow += minflow;
        for(i = pp[t]; i != -1; i = pp[edge[i].u])
        {
            edge[i].cap -= minflow;
            edge[i^1].cap += minflow;
        }
        mincost += dist[t] * minflow;
    }
    sumFlow = flow;
    return mincost;
}
int main()
{
    int n,m;
    int cas=1;
    while(~scanf("%d%d",&n,&m))
    {
        init();

        int s=0;
        int t=n+1;

        for(int i=0;i<m;i++)
        {
            int u,v,w1,w2;
            scanf("%d %d %d %d",&u,&v,&w1,&w2);
            addedge(u,v,1,w1);
            addedge(u,v,1,w1+w2);
        }

        addedge(s,s+1,2,0);
        addedge(t-1,t,2,0);

        int ans=MCMF(s,t,t);
        printf("Case %d: %d
",cas++,ans);
    }
    return 0;
}



原文地址:https://www.cnblogs.com/lxjshuju/p/6992105.html