[关闭]
@ZCDHJ 2018-09-29T15:54:17.000000Z 字数 1516 阅读 576

USACO4.4 Pollutant Control

网络流


Luogu

题目很明显是要求最小割,但是竟然要最小化边数?

我开始是想着将每一条边的费用设为 来跑费用流。。然后发现有反例

我们可以将每一条边的费用乘上一个大数再加上 ,然后再跑最大流

  1. #include <iostream>
  2. #include <cstdio>
  3. #include <cstring>
  4. #include <queue>
  5. typedef long long LL;
  6. #define int LL
  7. const int INF = 0x3f3f3f3f;
  8. const int MAXN = 32;
  9. const int MAXM = 1000;
  10. const int MOD = 10000;
  11. int n, m, edge = -1, maxFlow;
  12. int firstEdge[MAXN | 1], curEdge[MAXN | 1], depth[MAXN | 1];
  13. struct Edge {
  14. int to, f, nxt;
  15. Edge(){}
  16. Edge(int x, int y, int z) {
  17. to = y;
  18. f = z;
  19. nxt = firstEdge[x];
  20. }
  21. } e[MAXM << 1 | 1];
  22. inline int read() {
  23. register int x = 0;
  24. register char ch = getchar();
  25. while(!isdigit(ch)) ch = getchar();
  26. while(isdigit(ch)) {
  27. x = x * 10 + ch - '0';
  28. ch = getchar();
  29. }
  30. return x;
  31. }
  32. inline void addEdge(int x, int y, int z) {
  33. e[++edge] = Edge(x, y, z);
  34. firstEdge[x] = edge;
  35. }
  36. bool getDepth() {
  37. std::queue <int> q;
  38. memset(depth, 0, sizeof(depth));
  39. depth[1] = 1;
  40. q.push(1);
  41. do {
  42. int from = q.front();
  43. q.pop();
  44. for(int k = firstEdge[from]; ~k; k = e[k].nxt) {
  45. int to = e[k].to, f = e[k].f;
  46. if(f > 0 && !depth[to]) {
  47. depth[to] = depth[from] + 1;
  48. q.push(to);
  49. }
  50. }
  51. } while(!q.empty());
  52. return depth[n] > 0;
  53. }
  54. int Augment(int x, int flow) {
  55. if(x == n) return flow;
  56. for(int &k = curEdge[x]; ~k; k = e[k].nxt) {
  57. int to = e[k].to, f = e[k].f;
  58. if(f > 0 && depth[to] == depth[x] + 1) {
  59. int tmp = Augment(to, std::min(flow, f));
  60. if(tmp > 0) {
  61. e[k].f -= tmp;
  62. e[k ^ 1].f += tmp;
  63. return tmp;
  64. }
  65. }
  66. }
  67. return 0;
  68. }
  69. int Dinic() {
  70. int tmp = 0;
  71. while(getDepth()) {
  72. for(int i = 1; i <= n; ++i) curEdge[i] = firstEdge[i];
  73. while((tmp = Augment(1, INF)) > 0) maxFlow += tmp;
  74. }
  75. }
  76. signed main() {
  77. n = read();
  78. m = read();
  79. memset(firstEdge, -1, sizeof(firstEdge));
  80. for(int i = 1; i <= m; ++i) {
  81. int a = read(), b = read(), c = read();
  82. addEdge(a, b, c * MOD + 1);
  83. addEdge(b, a, 0);
  84. }
  85. Dinic();
  86. printf("%lld %lld\n", maxFlow / MOD, maxFlow % MOD);
  87. return 0;
  88. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注