对于无源汇问题,方法有两种.

1 从边的角度来处理. 新建超级源汇, 对于每一条有下界的边,x->y, 建立有向边 超级源->y ,容量为x->y下界,建立有向边 x-> 超级汇,容量为x->y下界.建立有向边 x->y,容量为x->y的上界减下界.

2 从点的角度来处理. 新建超级源汇,对于每个点流进的下界和为 in, 流出此点的下界和为out.如果in > out. 建立有向边 超级源->i,容量为in-out.反之,建立有向边 i->超级汇,容量为out-in.

如果超级源的每一条出边都满流,则存在一个可行流,可行流的流量就是每一条逆向边的流量+ 此边下界.

从点的角度的处理方法是边的处理方法的拓展.基于边的处理比较容易理解,但是复杂度较高.

下面是基于点的处理的程序:

   1:  /*
   2:      带上下界的可行流
   3:  */
   4:  #include<iostream>
   5:  #include<cmath>
   6:  #include<memory>
   7:  #include <string.h>
   8:  #include <cstdio>
   9:  using namespace std;
  10:   
  11:  #define V 300      // vertex
  12:  #define E  40800     // edge
  13:  #define INF 0x3F3F3F3F  // 1061109567
  14:   
  15:  int i,j,k;
  16:  #define REP(i,n) for((i)=0;(i)<(int)(n);(i)++)
  17:  #define snuke(c,itr) for(__typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)
  18:   
  19:  struct MaxFlow
  20:  {
  21:      struct Edge
  22:      {
  23:          int v, w, next;     //w for capicity
  24:          int lb,up;
  25:      } edge[E];
  26:   
  27:      int head[V];          // head[u]表示顶点u第一条邻接边的序号, 若head[u] = -1, u没有邻接边
  28:      int e;                // the index of the edge
  29:      int src, sink;
  30:      int net[V];              // 流入此节点的流的下界和 - 流出此节点的流的下界和,对于带上下界的来进行使用
  31:   
  32:   
  33:      void addedge(int  u, int v, int w, int lb = 0, int up = INF, int rw = 0)
  34:      {
  35:          edge[e].v = v;
  36:          edge[e].w= w;
  37:          edge[e].next = head[u];
  38:          edge[e].lb = lb, edge[e].up = up;
  39:          head[u] = e++;
  40:          // reverse edge  v -> u
  41:          edge[e].v = u;
  42:          edge[e].w = rw;
  43:          edge[e].lb = lb, edge[e].up = up;
  44:          edge[e].next = head[v];
  45:          head[v] = e++;
  46:      }
  47:   
  48:      int ISAP(int VertexNum )
  49:      {
  50:          int u, v, max_flow, aug, min_lev;
  51:          int curedge[V], parent[V], level[V];
  52:          int count[V], augment[V];
  53:   
  54:          memset(level, 0, sizeof(level));
  55:          memset(count, 0, sizeof(count));
  56:          REP(i,VertexNum+1) curedge[i] = head[i];
  57:          max_flow = 0;
  58:          augment[src] = INF;
  59:          parent[src] = -1;
  60:          u = src;
  61:   
  62:          while (level[src] < VertexNum)
  63:          {
  64:              if (u == sink)
  65:              {
  66:                  max_flow += augment[sink];
  67:                  aug = augment[sink];
  68:                  for (v = parent[sink]; v != -1; v = parent[v])
  69:                  {
  70:                      i = curedge[v];
  71:                      edge[i].w  -= aug;
  72:                      edge[i^1].w  += aug;
  73:                      augment[edge[i].v] -= aug;
  74:                      if (edge[i].w == 0) u = v;
  75:                  }
  76:              }
  77:              for (i = curedge[u]; i != -1; i = edge[i].next)
  78:              {
  79:                  v = edge[i].v;
  80:                  if (edge[i].w > 0 && level[u] == (level[v]+1))
  81:                  {
  82:                      augment[v] = min(augment[u], edge[i].w);
  83:                      curedge[u] = i;
  84:                      parent[v] = u;
  85:                      u = v;
  86:                      break;
  87:                  }
  88:              }
  89:              if (i == -1)
  90:              {
  91:                  if (--count[level[u]] == 0) break;
  92:                  curedge[u] = head[u];
  93:                  min_lev = VertexNum;
  94:                  for (i = head[u]; i != -1; i = edge[i].next)
  95:                      if (edge[i].w > 0)
  96:                          min_lev = min(level[edge[i].v], min_lev);
  97:                  level[u] = min_lev + 1;
  98:                  count[level[u]]++;
  99:                  if (u != src ) u = parent[u];
 100:              }
 101:          }
 102:          return max_flow;
 103:      }
 104:      void solve()
 105:      {
 106:          int T; cin>>T;
 107:          for(int cas =1; cas <=T; cas++)
 108:          {
 109:              int N,M; cin>>N>>M;
 110:              e = 0;
 111:              memset(head, -1, sizeof(head));
 112:              memset(net, 0, sizeof(net));
 113:              int a,b,c,d;
 114:              for(int i=1; i<=M;i++)
 115:              {
 116:                  scanf("%d%d%d%d", &a, &b, &c, &d);
 117:                  net[b] += c; net[a] -= c;
 118:                  addedge(a,b,d-c, c,d);
 119:              }
 120:              // 无源汇,这两个是super src, super sink.
 121:              src =N+1; sink = N+2;
 122:              for(int i=1; i<=N; i++)
 123:              {
 124:                  if(net[i] > 0)
 125:                      addedge(src, i, net[i]);
 126:                  else
 127:                      addedge(i, sink, -net[i]);
 128:              }
 129:              ISAP(N+2);
 130:              bool flag = true;
 131:              for (i = head[src]; i != -1; i = edge[i].next)
 132:              {
 133:                  if(edge[i].w !=0)
 134:                  {
 135:                      flag = false;
 136:                      break;
 137:                  }
 138:              }
 139:              if(flag)
 140:              {
 141:                  cout<<"YES"<<endl;
 142:                  for(int i=0; i<M;i++)
 143:                  {
 144:                      cout<<edge[i*2+1].w + edge[i*2+1].lb<<endl;
 145:                  }
 146:                  cout<<endl;
 147:              }else
 148:              {
 149:                  cout<<"NO"<<endl;
 150:                  cout<<endl;
 151:              }
 152:          }
 153:   
 154:      }
 155:  }sap;
 156:   
 157:  int main()
 158:  {
 159:  //    freopen("1.txt","r",stdin);
 160:      sap.solve();
 161:      return 0;
 162:  }

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

ZOJ 2314 带上下界的可行流的更多相关文章

  1. HDU Destroy Transportation system(有上下界的可行流)

    前几天正看着网络流,也正研究着一个有上下界的网络流的问题,查看了很多博客,觉得下面这篇概括的还是相当精确的: http://blog.csdn.net/leolin_/article/details/ ...

  2. [ACdream 1211 Reactor Cooling]无源无汇有上下界的可行流

    题意:无源无汇有上下界的可行流 模型 思路:首先将所有边的容量设为上界减去下界,然后对一个点i,设i的所有入边的下界和为to[i],所有出边的下界和为from[i],令它们的差为dif[i]=to[i ...

  3. ZOJ 2314 有上下界的网络流

    problemCode=2314">点击打开链接 题意:给定m条边和n个节点.每条边最少的流量和最多的流量.保证每一个节点的出入流量和相等,问能够形成吗,能够则输出每条边的流量 思路: ...

  4. BZOJ2406矩阵——有上下界的可行流+二分答案

    题目描述 输入 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. 输出 第一行,输出最小的答案: 样例输入 2 2 0 1 2 1 0 1 样例输出 1 ...

  5. 【BZOJ2406】矩阵 二分+有上下界的可行流

    [BZOJ2406]矩阵 Description Input 第一行两个数n.m,表示矩阵的大小. 接下来n行,每行m列,描述矩阵A. 最后一行两个数L,R. Output 第一行,输出最小的答案: ...

  6. SGU 194 Reactor Cooling Dinic求解 无源无汇有上下界的可行流

    题目链接 题意:有向图中有n(1 <= n <= 200)个点,无自环或者环的节点个数至少为3.给定每条边的最小流量和最大流量,问每条边的可行流量为多少? 思路:一般求解的网络流并不考虑下 ...

  7. ZOJ 2314 Reactor Cooling | 无源汇可行流

    题目: 无源汇可行流例题 http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=1314 题解: 证明什么的就算了,下面给出一种建图方式 ...

  8. bzoj 2406 二分+有源有汇上下界网络流可行流判定

    弱爆了,典型的行列建模方式,居然想不到,题做少了,总结少了...... 二分答案mid s----------------------->i行-----------------------> ...

  9. sgu 194 上下界网络流可行流判定+输出可行流

    #include <cstdio> #include <cstring> #define min(a,b) ((a)<(b)?(a):(b)) #define oo 0x ...

随机推荐

  1. 转:Android中Context详解 ---- 你所不知道的Context

    转:http://blog.csdn.net/qinjuning/article/details/7310620 转:http://blog.csdn.net/lmj623565791/article ...

  2. css优先机制

    样式的优先级 (外部样式)External style sheet <(内部样式)Internal style sheet <(内联样式)Inline style (内部样式就是css写在 ...

  3. 一场ACM一场梦——我的一年

    听着裁判倒计时比赛结束,看着全场鲜艳的气球,今天的结果是the last result i can image. 过几天给校赛出题,去年此时的我,还从来没有过竞赛的经验,只因为在大学开学前看了一点点c ...

  4. js中的相等与不等运算

    如果其中一个操作数的类型为 Boolean ,那么,首先将它转换为数字类型,false 转换为 0, true 将转换为 1. 如果其中一个操作数的类型是字符串,另外一个为数字类型,那么,将字符串转换 ...

  5. php curl 的用法 转载

    curl 是使用URL语法的传送文件工具,支持FTP.FTPS.HTTP HTPPS SCP SFTP TFTP TELNET DICT FILE和LDAP.curl 支持SSL证书.HTTP POS ...

  6. AMQ学习笔记 - 07. 持久性订阅

    概述 一般的订阅,订阅者必须时刻处于活跃状态,才不会遗漏任何信息:持久性订阅,当订阅者处于非活动状态时,代理会为它们保留信息,下一次连接之后推送给它们. 持久订阅 与一般的定于相比,持久性订阅需要: ...

  7. 阿里巴巴2013年实习生笔试题A

    一.单项选择题 1.下列说法不正确的是:(B) A.SATA硬盘的速度速度大约为500Mbps/s B.读取18XDVD光盘数据的速度为1Gbps C.前兆以太网的数据读取速度为1Gpbs D.读取D ...

  8. IOS数据解析JSON

    //非原创 作为一种轻量级的数据交换格式,json正在逐步取代xml,成为网络数据的通用格式. 有的json代码格式比较混乱,可以使用此“http://www.bejson.com/”网站来进行JSO ...

  9. 13.mariadb-rhce考试解题思路

    1.安装mariadb ①yum install -y mariadb mariadb-server 或者 yum groupinstall -y mariadb 2.备份和还原数据库 ①备份:mys ...

  10. MATLAB学习(3)

    matlab读取图像并转化为灰度图像 image = imread('C:\Users\Administrator\Desktop\图像降噪\src\original image\100.png'); ...