• POJ 2315 最小费用最大流


    从1走到N然后从N走回来的最短路程是多少? 转换为费用流来建模.

       1:  /**
       2:  因为e ==0 所以 pe[v]   pe[v]^1 是两条相对应的边
       3:  E[pe[v]].c -= aug;            E[pe[v]^1].c += aug;
       4:  
       5:  */
       6:  #include <queue>
       7:  #include <iostream>
       8:  #include <string.h>
       9:  #include <stdio.h>
      10:  #include <map>
      11:  using namespace std;
      12:  #define V 30010      // vertex
      13:  #define E 150010      // edge
      14:  #define INF 0x3F3F3F3F
      15:  struct MinCostMaxFlow
      16:  {
      17:      struct Edge
      18:      {
      19:          int v, next, cap, cost;  // cap 为容量, cost为单位流量费用
      20:      } edge[E];
      21:   
      22:      int head[V], pe[V], pv[V];            // 每个节点的第一条edge[idx]的编号.
      23:      int  dis[V];            // the shortest path to the src
      24:      bool vis[V];            // visted
      25:      // pe[v]  存放在增广路上到达v的边(u,v) 在edge[]的位置
      26:      // pv[u]  存放在增广路上从u出发的边(u,v) 在edge[]中的位置
      27:      int e, src, sink;            // the index of the edge
      28:      void addedge(int  u, int v, int cap, int cost)
      29:      {
      30:          edge[e].v = v, edge[e].cap = cap;
      31:          edge[e].cost = cost,edge[e].next = head[u], head[u] = e++;
      32:          edge[e].v = u, edge[e].cap = 0;
      33:          edge[e].cost = -1*cost, edge[e].next = head[v], head[v] = e++;
      34:      }
      35:      // 求最短路,不存在负环的时候,比 DFS快
      36:      int SPFABFS()
      37:      {
      38:          memset(vis, 0 ,sizeof(vis));
      39:          memset(pv, -1, sizeof(pv));
      40:          for(int i=0; i<V; i++) dis[i] = INF;
      41:          queue<int> Q;
      42:          Q.push(src), vis[src] = 1, dis[src] = 0;
      43:          while(!Q.empty())
      44:          {
      45:              int u = Q.front();
      46:              Q.pop(), vis[u] = 0;
      47:              for(int i=head[u]; i!=-1; i=edge[i].next)
      48:              {
      49:                  int v = edge[i].v;
      50:                  if(edge[i].cap > 0 &&  dis[v] > dis[u] + edge[i].cost  )
      51:                  {
      52:                      dis[v] = dis[u] + edge[i].cost;
      53:                      if(!vis[v]) Q.push(v),vis[v] = 1;
      54:                      pv[v] = u, pe[v] = i;
      55:                  }
      56:              }
      57:          }
      58:          if(dis[sink] == INF) return -2;          // can't from src to sink.
      59:          return dis[sink];
      60:      }
      61:   
      62:      pair<int,int> MCMF()
      63:      {
      64:          int maxflow = 0, mincost = 0;
      65:          while(SPFABFS())
      66:          {
      67:              if(pv[sink] == -1) break;
      68:              int aug = INF;
      69:              for(int i= sink; i!= src; i = pv[i])
      70:                  aug =min(aug, edge[pe[i]].cap);
      71:              maxflow += aug;
      72:              mincost += aug * dis[sink];
      73:              for(int i = sink; i!= src; i = pv[i])
      74:              {
      75:                  edge[pe[i]].cap -= aug;
      76:                  edge[pe[i]^1].cap += aug;
      77:              }
      78:          }
      79:          return make_pair(maxflow, mincost);
      80:      }
      81:   
      82:      /// 一定需要初始化的是 src, sink
      83:      void solve()
      84:      {
      85:          int N,M;
      86:          while(scanf("%d%d", &N , &M)!= EOF)
      87:          {
      88:              e=0;
      89:              memset(head, -1,sizeof(head));
      90:              for(int i=0; i<M; i++)
      91:              {
      92:                  int a, b, c;
      93:                  scanf("%d%d%d", &a, &b, &c);
      94:                  addedge(a, b,1,c);
      95:                  addedge(b, a,1, c);
      96:              }
      97:              src = 0;
      98:              sink = N+1;
      99:              addedge(src,1, 2, 0);
     100:              addedge(N, sink, 2, 0);
     101:              pair<int,int> ret = MCMF();
     102:              cout<<ret.second<<endl;
     103:          }
     104:      }
     105:  } mcmf;
     106:   
     107:  int main()
     108:  {
     109:      mcmf.solve();
     110:      return 0;
     111:  }

  • 相关阅读:
    计算欧拉函数值
    矩阵快速幂
    约瑟夫环数学公式
    整型输出输入优化
    计算机设计第三章
    计算机设计第二章
    计算机设计
    阿里巴巴秋招2017客户端附加题
    程序设计基本概念
    c++面试题
  • 原文地址:https://www.cnblogs.com/sosi/p/3715436.html
Copyright © 2020-2023  润新知