<address id="nhfpd"></address>

                <sub id="nhfpd"></sub>

                  【网络流】网络扩容

                  【问题描述】
                  	给定一张有向图,每条边都有一个容量C和一个扩容费用W。这里扩容费用是指将容量扩大1所需的费用。求:
                  1、 在不扩容的情况下,1到N的最大流;
                  2、 将1到N的最大流增加K所需的最小扩容费用。
                  【输入格式】network.in
                  	输入文件的第一行包含三个整数N,M,K,表示有向图的点数、边数以及所需要增加的流量。
                  	接下来的M行每行包含四个整数u,v,C,W,表示一条从u到v,容量为C,扩容费用为W的边。
                  【输出格式】network.out
                  	输出文件一行包含两个整数,分别表示问题1和问题2的答案。
                  【输入样例】
                  5 8 2
                  1 2 5 8
                  2 5 9 9
                  5 1 6 2
                  5 1 1 8
                  1 2 8 7
                  2 5 4 9
                  1 2 1 1
                  1 4 2 1
                  【输出样例】
                  	13 19
                  【数据规模】
                  	30%的数据中,N<=100
                  	100%的数据中,N<=1000,M<=5000,K<=10
                  这是一道最大流加最小费用流的问题。

                  最大流就不再多说了。

                  求出了最大流之后有个残量网络,将这些边的费用设为0(原图中剩余的流量免费),重新加入一些边(前提是原图中有这些边,于是),流量为k,费用为扩容费用,再加一个超级源,连一条容量为k,费用为0的边(限制流量最大为k),最后求一次最小费用流即可。

                  Accode:

                  #include <cstdio>
                  #include <cstdlib>
                  #include <string>
                  #include <algorithm>
                  #define min(a, b) ((a) < (b) ? (a) : (b))
                  #define max(a, b) ((a) > (b) ? (a) : (b))
                  
                  const char fi[] = "network.in";
                  const char fo[] = "network.out";
                  const int maxN = 1010;
                  const int SIZE = 0x3ff;
                  const int MAX = 0x3f3f3f3f;
                  const int MIN = ~MAX;
                  
                  struct Edge
                  {
                      int u, v, f, c;
                      Edge *next, *back;
                  };
                  
                  Edge *edge[maxN];
                  Edge *pre[maxN];
                  bool mp[maxN][maxN];
                  int w[maxN][maxN];
                  int d[maxN];
                  int cnt[maxN];
                  int q[SIZE + 1];
                  int n, m, K, S = 1, T, f, r;
                  
                  void init_file()
                  {
                      freopen(fi, "r", stdin);
                      freopen(fo, "w", stdout);
                      return;
                  }
                  
                  inline int getint()
                  {
                      int res = 0; char tmp;
                      while (!isdigit(tmp = getchar()));
                      do res = (res << 3) + (res << 1) + tmp - '0';
                      while (isdigit(tmp = getchar()));
                      return res;
                  }
                  
                  inline void insert(int u, int v, int f, int c)
                  {
                      Edge *p = new Edge;
                      p -> u = u; p -> v = v;
                      p -> f = f; p -> c = c;
                      p -> next = edge[u];
                      edge[u] = p;
                      p = new Edge;
                      p -> u = v; p -> v = u;
                      p -> f = 0; p -> c = -c;
                      p -> next = edge[v];
                      edge[v] = p;
                      edge[u] -> back = edge[v];
                      edge[v] -> back = edge[u];
                      return;
                  }    
                  
                  void readdata()
                  {
                      T = n = getint(); m = getint(); K = getint();
                      for (; m; --m)
                      {
                          int u = getint(), v = getint(),
                          f = getint(), c = getint();
                          mp[u][v] = 1;
                  	//先用mp数组记录一下原图中有哪些边。
                          w[u][v] = w[u][v] ? min(w[u][v], c) : c;
                  	//记录扩容费用。
                          insert(u, v, f, 0);
                      }
                      return;
                  }
                  
                  int Sap(int u, int Lim)
                  {
                      if (u == T) return Lim;
                      int tmp = 0;
                      for (Edge *p = edge[u]; p; p = p -> next)
                      if (p -> f > 0 && d[u] == d[p -> v] + 1)
                      {
                          int k = Sap(p -> v, min(p -> f, Lim - tmp));
                          p -> f -= k;
                          p -> back -> f += k;
                          if ((tmp += k) == Lim) return tmp;
                      }
                      if (d[S] >= n) return tmp;
                      if ((--cnt[d[u]]) == 0) d[S] = n;
                      ++cnt[++d[u]];
                      return tmp;
                  }
                  
                  int Spfa()
                  {
                      memset(pre, 0, sizeof pre);
                      memset(d, 0x3f, sizeof d);
                      memset(cnt, 0, sizeof cnt);
                      f = r = 0;
                      d[S] = 0;
                      ++cnt[q[r++] = S];
                      r &= SIZE;
                      while (f != r)
                      {
                          int u = q[f++];
                          f &= SIZE;
                          --cnt[u];
                          for (Edge *p = edge[u]; p; p = p -> next)
                          if (p -> f > 0)
                          {
                              int v = p -> v;
                              int c = p -> c;
                              if (d[u] + c < d[v])
                              {
                                  d[v] = d[u] + c;
                                  pre[v] = p;
                                  if (!cnt[v])
                                  {
                                      ++cnt[q[r++] = v];
                                      r &= SIZE;
                                  }
                              }
                          }
                      }
                      return pre[T] != NULL;
                  }
                  
                  int min_fee()
                  {
                      int ans = 0;
                      while (Spfa())
                      {
                          int max_flow = MAX;
                          for (Edge *p = pre[T]; p; p = pre[p -> u])
                              max_flow = min(max_flow, p -> f);
                          for (Edge *p = pre[T]; p; p = pre[p -> u])
                          {
                              p -> f -= max_flow;
                              p -> back -> f += max_flow;
                          }
                          ans += d[T] * max_flow;
                      }
                      return ans;
                  }
                  
                  void work()
                  {
                      int ans = 0;
                      cnt[0] = n;
                      while (d[S] < n) ans += Sap(S, MAX);
                      for (int u = 1; u < n + 1; ++u)
                      for (int v = 1; v < n + 1; ++v)
                          if (mp[u][v]) insert(u, v, MAX, w[u][v]);
                      insert(S = 0, 1, K, 0);
                      printf("%d %d\n", ans, min_fee());
                      return;
                  }
                  
                  int main()
                  {
                      init_file();
                      readdata();
                      work();
                      return 0;
                  }
                  
                  #undef min
                  #undef max
                  再贴一个求费用流时没有退流的骗分程序,能过90分。
                  #include <cstdio>
                  #include <cstdlib>
                  #include <string>
                  #include <algorithm>
                  #define min(a, b) ((a) < (b) ? (a) : (b))
                  #define max(a, b) ((a) > (b) ? (a) : (b))
                  
                  const char fi[] = "network.in";
                  const char fo[] = "network.out";
                  const int maxN = 1010;
                  const int SIZE = 0x3ff;
                  const int MAX = 0x3f3f3f3f;
                  const int MIN = ~MAX;
                  
                  struct Edge
                  {
                      int u, v, f, c;
                      Edge *next, *back;
                  };
                  
                  Edge *edge[maxN];
                  int d[maxN];
                  int cnt[maxN];
                  int q[SIZE + 1];
                  int n, m, K, S = 1, T, f, r;
                  
                  void init_file()
                  {
                      freopen(fi, "r", stdin);
                      freopen(fo, "w", stdout);
                      return;
                  }
                  
                  inline int getint()
                  {
                      int res = 0; char tmp;
                      while (!isdigit(tmp = getchar()));
                      do res = (res << 3) + (res << 1) + tmp - '0';
                      while (isdigit(tmp = getchar()));
                      return res;
                  }
                  
                  inline void insert(int u, int v, int f, int c)
                  {
                      for (Edge *p = edge[u]; p; p = p -> next)
                      if (p -> v == v)
                      {
                          p -> f += f;
                          p -> c = min(p -> c, c);
                          return;
                      }
                      Edge *p = new Edge;
                      p -> u = u; p -> v = v;
                      p -> f = f; p -> c = c;
                      p -> next = edge[u];
                      edge[u] = p;
                      p = new Edge;
                      p -> u = v; p -> v = u;
                      p -> f = 0;
                      p -> c = MAX;
                      p -> next = edge[v];
                      edge[v] = p;
                      edge[u] -> back = edge[v];
                      edge[v] -> back = edge[u];
                      return;
                  }
                  
                  void readdata()
                  {
                      T = n = getint(); m = getint(); K = getint();
                      for (; m; --m)
                      {
                          int u = getint(), v = getint(),
                          f = getint(), c = getint();
                          insert(u, v, f, c);
                      }
                      return;
                  }
                  
                  int Sap(int u, int Lim)
                  {
                      if (u == T) return Lim;
                      int tmp = 0;
                      for (Edge *p = edge[u]; p; p = p -> next)
                      if (p -> f > 0 && d[u] == d[p -> v] + 1)
                      {
                          int k = Sap(p -> v, min(p -> f, Lim - tmp));
                          p -> f -= k;
                          p -> back -> f += k;
                          if ((tmp += k) == Lim) return tmp;
                      }
                      if (d[S] >= n) return tmp;
                      if ((--cnt[d[u]]) == 0) d[S] = n;
                      ++cnt[++d[u]];
                      return tmp;
                  }
                  
                  int Spfa()
                  {
                      memset(d, 0x3f, sizeof d);
                      memset(cnt, 0, sizeof cnt);
                      d[S] = 0;
                      ++cnt[q[r++] = S];
                      r &= SIZE;
                      while (f != r)
                      {
                          int u = q[f++];
                          f &= SIZE;
                          --cnt[u];
                          for (Edge *p = edge[u]; p; p = p -> next)
                          if (p -> c < MAX)
                          {
                              int v = p -> v;
                              int c = (p -> c) * max(0, K - p -> f);
                              if (d[u] + c < d[v])
                              {
                                  d[v] = d[u] + c;
                                  if (!cnt[v])
                                  {
                                      ++cnt[q[r++] = v];
                                      r &= SIZE;
                                  }
                              }
                          }
                      }
                      return d[T];
                  }
                  
                  void work()
                  {
                      int ans = 0;
                      cnt[0] = n;
                      while (d[S] < n) ans += Sap(S, MAX);
                      printf("%d %d\n", ans, K ? Spfa() : 0);
                      return;
                  }
                  
                  int main()
                  {
                      init_file();
                      readdata();
                      work();
                      return 0;
                  }
                  
                  #undef min
                  #undef max
                  相关文章
                  相关标签/搜索
                  何仙姑六肖期期准资料 岑巩县| 漠河县| 江安县| 韶关市| 如皋市| 罗甸县| 枝江市| 武胜县| 汉寿县| 元朗区| 苍南县| 霍山县| 湘乡市| 义马市| 扶余县| 章丘市| 库伦旗| 若羌县| 剑川县| 大庆市| 合阳县| 噶尔县| 平陆县| 兴化市| 绥化市| 马鞍山市| 丰台区| 霍林郭勒市| 嫩江县| 平南县| 全南县| 高邑县| 龙州县| 栾城县| 澄江县| 增城市| 亳州市| 疏附县| 汪清县| 韩城市| 宣恩县| 东兰县| 兰溪市| 离岛区| 林州市| 吉安市| 定边县| 香格里拉县| 鄂托克旗| 德安县| 长汀县| 舒城县| 涞源县| 类乌齐县| 阳城县| 宁阳县| 枣庄市| 镇巴县| 新巴尔虎右旗| 西藏| 固始县| 得荣县| 凤冈县| 乐昌市| 庆安县| 洛川县| 大竹县| 静安区| 濮阳市| 敦煌市| 南康市| 辉南县| 海门市| 黄冈市| 金阳县| 佛山市| 泰和县| 芮城县| 武鸣县| 淮安市| 台北市| 陆河县| 福州市| 蕉岭县| 卓尼县| 富宁县| 定日县| 四子王旗| 永城市| 开封市| 海口市| 津市市| 奈曼旗| 涿州市| 咸阳市| 济阳县| 侯马市| 文山县| 疏勒县| 明溪县| 韩城市| 南木林县| 罗平县| 揭西县| 唐河县| 宜兴市| 宜君县| 宁德市| 铁力市| 仁布县| 北安市| 平乐县| 镇原县| 凌源市| 惠安县| 嘉兴市| 五寨县| 香港| 耒阳市| 九江市| 绥中县| 重庆市| 五寨县| 赤壁市| 孟连| 团风县| 富源县| 林周县| 新和县| 区。| 浮梁县| 东台市| 桃园县| 会泽县| 遂宁市| 德兴市| 昌平区| 瑞昌市| 靖西县| 且末县| 鹿泉市| 宜丰县| 吉首市| 始兴县| 海丰县| 日照市| 杭州市| 永定县| 怀柔区| 麻城市| 卢龙县| 亳州市| 楚雄市| 鸡西市| 柘荣县| 佛山市| 双流县| 左贡县| 静海县| 金昌市| 天峨县| 景东| 林西县| 卫辉市| 舟曲县| 闵行区| 墨竹工卡县| 都昌县| 涿鹿县| 庆元县| 普宁市| 临泽县| 崇州市| 萝北县| 滨海县| 大同县| 灵寿县| 徐闻县| 陈巴尔虎旗| 吴桥县| 麻城市| 中方县| 鄂伦春自治旗| 石城县| 许昌市| 措勤县| 伊吾县| 特克斯县| 商南县| 岚皋县| 晴隆县| 罗山县| 五河县| 霍城县| 博兴县| 水城县| 杨浦区| 英德市| 平利县| 普兰县| 鲜城| 东方市| 拉萨市| 乌兰县| 拉孜县| 崇仁县| 洪洞县| 大悟县| 滨海县| 股票| 独山县| 大庆市| 江门市| 高要市| 沙坪坝区| 会同县| 巩留县| 沙田区| 沙雅县| 涞源县| 毕节市| 洪江市| 甘德县| 德阳市| 湖州市| 沽源县| 偏关县| 闽侯县| 邵东县| 安徽省| 长宁区| 饶阳县| 宁都县| 临漳县| 宁远县| 镶黄旗| 贵阳市| 汾阳市| 巴南区| 绥中县| 新田县| 南丹县| 图们市| 东兰县| 红河县| 清涧县| 尼木县| 呼和浩特市| 海兴县| 边坝县| 天等县| 绥棱县| 大宁县| 北海市| 公主岭市| 邹平县| 营山县| 博客| 龙陵县| 麦盖提县| 浠水县| 临朐县| 建始县| 乳山市| 烟台市| 搜索| 依兰县| 都昌县| 乌什县| 吉安市| 新沂市| 惠来县| 和平区| 乐平市| 砚山县| 汶川县| 泸定县| 大关县| 阿坝县| 项城市| 扎鲁特旗| 陆良县| 张家港市| 寿宁县| 长宁县| 清涧县| 东阳市| 安福县| 永丰县| 东平县| 长汀县| 桂林市| 长岭县| 芜湖市| 丰都县| 铜陵市| 花莲县| 蓬溪县| 邹平县| 务川| 江华| 龙里县| 佛教| 从化市| 天柱县| 成都市| 江陵县| 滨海县| 隆尧县| 尼勒克县| 富民县| 永清县| 百色市| 榆林市| 阿瓦提县| 定州市| 南康市| 德格县| 天峨县| 东源县| 平南县| 吉安市| 亚东县| 济南市| 如东县| 满洲里市| 墨脱县| 岳阳市| 海口市| 大冶市| 涟源市| 东安县| 东阳市| 平安县| 阿瓦提县| 洱源县| 永济市| 阿鲁科尔沁旗| 湘潭市| 四川省| 沁阳市| 满城县| 荥经县| 临江市| 镇雄县| 黄大仙区| 米泉市| 宜兴市| 新化县| 江口县| 家居| 稻城县| 深圳市| 宿迁市| 佳木斯市| 白沙| 甘南县| 临漳县| 平利县| 吉安市| 共和县| 伊川县| 葫芦岛市| 仁怀市| 鄂托克前旗| 裕民县| 江源县| 上高县| 乐平市| 青田县| 通榆县| 平谷区| 米脂县| 乐陵市| 财经| 舞阳县| 河津市| 东兴市| 博湖县| 和龙市| 秭归县| 长寿区| 姚安县| 兴海县| 新宾| 饶平县| 宁强县| 徐闻县| 沈阳市| 长顺县| 宁城县| 荥阳市| 二连浩特市| 杭锦后旗| 益阳市| 兴海县| 新余市| 韶关市| 皮山县| 仪征市| 砀山县| 龙海市| 梨树县| 呼图壁县| 上饶市| 东乌珠穆沁旗| 南投县| 安岳县| 滨海县| 林芝县| 高安市| 久治县| 休宁县| 邻水| 卢氏县| 水富县| 米泉市| 微博| 嘉黎县| 祥云县| 郁南县| 揭东县| 天全县| 淄博市| 太和县| 文山县| 尚志市| 泸定县| 吉木乃县| 崇文区| 洪雅县| 泊头市| 临海市| 大方县| 海原县| 南投县| 鹤庆县| 巴彦淖尔市| 陆河县| 双流县| 定陶县| 高邮市| 德令哈市| 桐庐县| 昌都县| 济南市| 保亭| 洮南市| 栾川县| 九龙县| 镇坪县| 潞西市| 泗阳县| 河北省| 额济纳旗| 绍兴县| 闻喜县| 昌图县| 崇明县| 乌鲁木齐县| 息烽县| 永兴县| 迁安市| 田东县| 门源| 河南省| 汕头市| 万山特区| 昆明市| 克什克腾旗| 渭南市| 永仁县| 台江县| 兴业县| 平江县| 闽侯县| 双江| 阜南县| 兴仁县| 时尚| 龙游县| 夹江县| 杭锦后旗| 沂源县| 神农架林区| 镇坪县| 康乐县| 天气| 堆龙德庆县| 尚义县| 苗栗县| 米林县| 济宁市| 莱西市| 塘沽区| 博罗县| 四平市| 大埔县| 日喀则市| 深州市| 嘉荫县| 内乡县| 古蔺县| 盈江县| 肃北| 汉沽区| 二连浩特市| 枣庄市| 滁州市| 开鲁县| 且末县| 大荔县| 海丰县| 怀柔区| 保康县| 财经| 农安县| 茌平县| 巴青县| 长治县| 兴安盟| 仙居县| 泗洪县| 横峰县| 巴林右旗| 汉阴县| 眉山市| 镇平县| 大兴区| 威信县| 黑龙江省| 许昌市| 油尖旺区| 瑞金市| 富源县| 时尚| 玉田县| 永定县| 泸溪县| 庆阳市| 秦安县| 岗巴县| 温泉县| 梓潼县| 茶陵县| 达拉特旗| 巧家县| 霍林郭勒市| 贵南县| 平潭县| 白河县| 邯郸县| 德安县| 红原县| 罗城| 焉耆| 瑞金市| 含山县| 大安市| 大宁县| 关岭| 绿春县| 红原县| 镇江市| 洛浦县| 临高县| 英德市| 怀仁县| 禹城市| 榆林市| 永吉县| 修水县| 龙南县| 西林县| 惠水县| 泸溪县| 襄樊市| 东至县| 健康| 汕头市| 通州市| 平定县| 嵩明县| 肇源县| 理塘县| 游戏| 翼城县| 夏津县| 温宿县| 读书| 仁寿县| 壤塘县| 新郑市| 凌云县| 新巴尔虎右旗| 陵川县| 屯门区| 苍溪县| 孙吴县| 泾川县| 安福县| 屏东市| 许昌市| 永平县| 沧州市| 黑龙江省| 龙门县| 雷波县| 商丘市| 万宁市| 溆浦县| 广丰县| 哈尔滨市| 凉城县| 渝北区| http://www.hz0j0r5vo.fun http://www.jx1870handv.fun http://jx1870issuev.fun http://wap.jx1870frazev.fun http://www.jx1870fieldv.fun http://hz0j3r9vo.fun http://www.jx1870fuelv.fun http://www.hz0j3r3vo.fun http://m.jx1870gardenv.fun http://wap.jx1870evenv.fun http://jx1870instruzentv.fun http://www.jx1870fishv.fun http://wap.jx1870gainv.fun http://jx1870fashionv.fun http://wap.hz0j3r4vo.fun http://m.jx1870gov.fun http://m.jx1870headv.fun http://www.jx1870fashionv.fun