• UVa 1658 Admiral(最小费用最大流)


     

    拆点费用流

    ---------------------------------------------------------------------

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    #include<queue>
    #include<vector>
     
    #define rep(i,n) for(int i=0;i<n;++i)
    #define clr(x,c) memset(x,c,sizeof(x))
     
    using namespace std;
     
    const int maxn=2000+5;
    const int inf=0x3f3f3f3f;
     
    struct Edge {
    int from,to,cap,flow,cost;
    };
     
    struct mcmf {
    bool inq[maxn];
    int d[maxn];
    int a[maxn];
    int p[maxn];
    int n,s,t;
    vector<int> g[maxn];
    vector<Edge> edges;
    void init(int n) {
    this->n=n;
    rep(i,n) g[i].clear();
    edges.clear();
    }
    void addEdge(int u,int v,int cap,int cost) {
    edges.push_back( (Edge) {u,v,cap,0,cost} );
    edges.push_back( (Edge) {v,u,0,0,-cost} );
    g[u].push_back(edges.size()-2);
    g[v].push_back(edges.size()-1);
    }
    bool spfa(int &flow,int &cost) {
    clr(d,inf); clr(inq,0);
    d[s]=0; inq[s]=1; p[s]=0; a[s]=inf;
    queue<int> q;
    q.push(s);
    while(!q.empty()) {
    int x=q.front(); q.pop();
    inq[x]=0;
    rep(i,g[x].size()) {
    Edge &e=edges[g[x][i]];
    if(d[e.to]>d[x]+e.cost && e.cap>e.flow) {
    d[e.to]=d[x]+e.cost;
    p[e.to]=g[x][i];
    a[e.to]=min(a[x],e.cap-e.flow);
    if(!inq[e.to]) { q.push(e.to); inq[e.to]=1; }
    }
    }
    }
    if(d[t]==inf) return false;
    flow+=a[t];
    cost+=d[t]*a[t];
    int x=t;
    while(x!=s) {
    edges[p[x]].flow+=a[t];
    edges[p[x]^1].flow-=a[t];
    x=edges[p[x]].from;
    }
    return true;
    }
    int minCost(int s,int t) {
    this->s=s; this->t=t;
    int flow=0,cost=0;
    while(spfa(flow,cost));
    return cost;
    }
    } g;
      
    int main()
    {
    // freopen("test.in","r",stdin);
    // freopen("test.out","w",stdout);
    int n,m;
    while(scanf("%d%d",&n,&m)==2) {
    g.init(n*2+1);
    int a,b,c;
    while(m--) {
    scanf("%d%d%d",&a,&b,&c);
    if(a>1 && a<n) a+=n;
    g.addEdge(a,b,1,c);
    }
    for(int i=2;i<n;++i) g.addEdge(i,i+n,1,0);
    g.addEdge(0,1,2,0); g.addEdge(n,n*2,2,0);
    printf("%d ",g.minCost(0,n*2));
    }
    return 0;
    }
     

    ---------------------------------------------------------------------

  • 相关阅读:
    西瓜书的读书笔记
    Tensorflow-gpu在windows10上的安装(anaconda)
    php 设置报错等级
    PHP 类型比较表
    PHP中的定界符格式
    php进制转换函数
    php魔法常量
    php中双$$与多$$
    php引用传值
    CSS3过渡效果实现菜单划出效果
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4390906.html
Copyright © 2020-2023  润新知