POJ 3801 有上下界最小流

   1:  /**
   2:      POJ 3801 有上下界的最小流
   3:  
   4:  1、对supersrc到supersink 求一次最大流,记为f1。(在有源汇的情况下,先使整个网络趋向必须边尽量满足的情况)
   5:  2、添加一条边sink -> src,流量上限为INF,这条边记为p。(构造无源汇网络)
   6:  3、对supersrc到supersink再次求最大流,记为f2,这里判断是否为可行流。(要判断可行,必须先构造无源汇网络流,因此要再次求最大流)
   7:  
   8:      此网络流的最小流即为 sink -> src 的流量
   9:  */
  10:   
  11:  #include<iostream>
  12:  #include<cmath>
  13:  #include<memory>
  14:  #include <string.h>
  15:  #include <cstdio>
  16:  #include <vector>
  17:  using namespace std;
  18:   
  19:  #define V 150      // vertex
  20:  #define E  (V*V)     // edge
  21:  #define INF 0x3F3F3F3F  // 1061109567
  22:   
  23:  int i,j,k;
  24:  #define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
  25:  #define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
  26:   
  27:  struct MaxFlow
  28:  {
  29:      struct Edge
  30:      {
  31:          int v, w, next;     //w for capicity
  32:          int lb,up;
  33:      } edge[E];
  34:   
  35:      int head[V];          // head[u]表示顶点u第一条邻接边的序号, 若head[u] = -1, u没有邻接边
  36:      int e;                // the index of the edge
  37:      int src, sink;
  38:      int net[V];              // 流入此节点的流的下界和 - 流出此节点的流的下界和,对于带上下界的来进行使用
  39:   
  40:   
  41:      void addedge(int  u, int v, int w, int lb = 0, int up = INF, int rw = 0)
  42:      {
  43:          edge[e].v = v;
  44:          edge[e].w= w;
  45:          edge[e].next = head[u];
  46:          edge[e].lb = lb, edge[e].up = up;
  47:          head[u] = e++;
  48:          // reverse edge  v -> u
  49:          edge[e].v = u;
  50:          edge[e].w = rw;
  51:          edge[e].lb = lb, edge[e].up = up;
  52:          edge[e].next = head[v];
  53:          head[v] = e++;
  54:      }
  55:   
  56:      int ISAP(int VertexNum )
  57:      {
  58:          int u, v, max_flow, aug, min_lev;
  59:          int curedge[V], parent[V], level[V];
  60:          int count[V], augment[V];
  61:   
  62:          memset(level, 0, sizeof(level));
  63:          memset(count, 0, sizeof(count));
  64:          REP(i,VertexNum+1) curedge[i] = head[i];
  65:          max_flow = 0;
  66:          augment[src] = INF;
  67:          parent[src] = -1;
  68:          u = src;
  69:   
  70:          while (level[src] < VertexNum)
  71:          {
  72:              if (u == sink)
  73:              {
  74:                  max_flow += augment[sink];
  75:                  aug = augment[sink];
  76:                  for (v = parent[sink]; v != -1; v = parent[v])
  77:                  {
  78:                      i = curedge[v];
  79:                      edge[i].w  -= aug;
  80:                      edge[i^1].w  += aug;
  81:                      augment[edge[i].v] -= aug;
  82:                      if (edge[i].w == 0) u = v;
  83:                  }
  84:              }
  85:              for (i = curedge[u]; i != -1; i = edge[i].next)
  86:              {
  87:                  v = edge[i].v;
  88:                  if (edge[i].w > 0 && level[u] == (level[v]+1))
  89:                  {
  90:                      augment[v] = min(augment[u], edge[i].w);
  91:                      curedge[u] = i;
  92:                      parent[v] = u;
  93:                      u = v;
  94:                      break;
  95:                  }
  96:              }
  97:              if (i == -1)
  98:              {
  99:                  if (--count[level[u]] == 0) break;
 100:                  curedge[u] = head[u];
 101:                  min_lev = VertexNum;
 102:                  for (i = head[u]; i != -1; i = edge[i].next)
 103:                      if (edge[i].w > 0)
 104:                          min_lev = min(level[edge[i].v], min_lev);
 105:                  level[u] = min_lev + 1;
 106:                  count[level[u]]++;
 107:                  if (u != src ) u = parent[u];
 108:              }
 109:          }
 110:          return max_flow;
 111:      }
 112:      void solve()
 113:      {
 114:          int n, m;
 115:          while (scanf("%d %d", &n, &m) != EOF)
 116:          {
 117:              if (n+m == 0) break;
 118:              e = 0;
 119:              memset(head, -1, sizeof(head));
 120:              memset(net, 0, sizeof(net));
 121:   
 122:              int s = n+1, t = n+2;
 123:              src = n+3, sink = n+4;
 124:              char a[5], b[5];
 125:              int c;
 126:              while (m--)
 127:              {
 128:                  scanf("%s %s %d", a, b, &c);
 129:                  int u, v;
 130:                  if (a[0] == '+') u = s;
 131:                  else sscanf(a, "%d", &u);   // 注意这里读取信息
 132:                  if (b[0] == '-') v = t;
 133:                  else sscanf(b, "%d", &v);
 134:                  net[v] += c, net[u] -= c;
 135:                  addedge(u,v,INF,c, INF);
 136:              }
 137:              vector<int> CE;
 138:              for(int i=1; i<=n+2; i++)
 139:              {
 140:                  if(net[i] >=0)
 141:                  {
 142:                      CE.push_back(e);
 143:                      addedge(src, i, net[i]);
 144:                  }
 145:                  else
 146:                  {
 147:                      CE.push_back(e);
 148:                      addedge(i, sink, -net[i]);
 149:                  }
 150:              }
 151:              int flow = 0;
 152:              flow =  ISAP(n+4);
 153:              int p = e;
 154:              addedge(t, s, INF, 0, INF);
 155:              flow += ISAP(n+4);
 156:              bool flag = true;
 157:              for(int i= 0; i< CE.size(); i++)
 158:              {
 159:                  if(edge[CE[i]].w !=0)
 160:                  {
 161:                      flag = false;
 162:                      break;
 163:                  }
 164:              }
 165:              if (!flag)
 166:                  printf("impossible
");
 167:              else
 168:                  printf("%d
", edge[p^1].w);
 169:          }
 170:      }
 171:  } sap;
 172:   
 173:  int main()
 174:  {
 175:  //    freopen("1.txt","r",stdin);
 176:      sap.solve();
 177:      return 0;
 178:  }
原文地址:https://www.cnblogs.com/sosi/p/3716716.html