Advertisement
a53

Dyson

a53
Oct 3rd, 2020 (edited)
266
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.14 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. using Ip = pair <int, int>;
  6. using Vip = vector <Ip>;
  7. using Vi = vector <int>;
  8. using V2i = vector <Vi>;
  9. using Vi64 = vector <int64_t>;
  10. using Qi = queue <int>;
  11. constexpr int64_t Inf = 1LL * numeric_limits <int>::max ();
  12.  
  13. ifstream fin("dyson.in");
  14. ofstream fout("dyson.out");
  15.  
  16. template <class T = int64_t>
  17. class Dinic {
  18. public:
  19. Dinic(int n, int s, int t):
  20. V(n), Source(s), Sink(t) {
  21. Adj.resize(V), Level.resize(V), Ptr.resize(V);
  22. }
  23. void addEdge(int u, int v, T cap) {
  24. if(u == v)
  25. return;
  26. Edges.emplace_back(u, v, cap);
  27. Adj[u].emplace_back((int)Edges.size () - 1);
  28. Edges.emplace_back(v, u, 0);
  29. Adj[v].emplace_back((int)Edges.size () - 1);
  30. }
  31. T maxFlow() {
  32. T flow = 0;
  33. while(true) {
  34. fill(Level.begin (), Level.end(), -1);
  35. Level[Source] = 0, Q.push(Source);
  36. if(!bfs()) break;
  37. fill(Ptr.begin (), Ptr.end(), 0);
  38. while(T pushed = dfs (Source, Inf))
  39. flow += pushed;
  40. }
  41. return flow;
  42. }
  43. private:
  44. class FlowEdge {
  45. public:
  46. FlowEdge(int from, int to, T capacity):
  47. from(from), to(to), capacity(capacity) {
  48. }
  49. private:
  50. int from, to;
  51. T capacity, flow = 0;
  52. friend Dinic;
  53. };
  54. using Vf = vector <FlowEdge>;
  55. Vf Edges;
  56. V2i Adj;
  57. int V, Source, Sink;
  58. Vi Level, Ptr;
  59. Qi Q;
  60. bool bfs() {
  61. while(!Q.empty()) {
  62. int v = Q.front();
  63. Q.pop();
  64. for(const auto& it: Adj[v]) {
  65. if(Level[Edges[it].to] != -1 || Edges[it].capacity - Edges[it].flow < 1LL)
  66. continue;
  67. Level[Edges[it].to] = Level[v] + 1;
  68. Q.push(Edges[it].to);
  69. }
  70. }
  71. return Level[Sink] != -1;
  72. }
  73. T dfs(int v, T pushed) {
  74. if(!pushed)
  75. return 0;
  76. if(v == Sink)
  77. return pushed;
  78. for(int& cit = Ptr[v]; cit < (int)Adj[v].size(); ++cit) {
  79. int it = Adj[v][cit], u = Edges[it].to;
  80. if(Level[u] != Level[v] + 1 || Edges[it].capacity - Edges[it].flow < 1LL)
  81. continue;
  82. T send = dfs(u, min(pushed, Edges[it].capacity - Edges[it].flow));
  83. if(!send)
  84. continue;
  85. Edges[it].flow += send;
  86. Edges[it ^ 1].flow -= send;
  87. return send;
  88. }
  89. return 0;
  90. }
  91. };
  92.  
  93. int n, m, k, q, u, v;
  94. int64_t w;
  95. Vip Special;
  96. Vi64 Val, Cut, DP;
  97.  
  98. inline void DFS(int edge, int mask, Dinic <int64_t>& Graph, int64_t flow) {
  99. if(edge == k)
  100. Cut[mask] = flow;
  101. else {
  102. int u = Special[edge].first, v = Special[edge].second;
  103. // case ON
  104. {
  105. auto NGraph = Graph;
  106. NGraph.addEdge(0, u, Inf), NGraph.addEdge(v, n - 1, Inf);
  107. int64_t nflow = flow + NGraph.maxFlow();
  108. DFS(edge + 1, mask | (1 << edge), NGraph, nflow);
  109. }
  110. // case OUT
  111. {
  112. Graph.addEdge(u, v, Inf);
  113. int64_t nflow = flow + Graph.maxFlow();
  114. DFS(edge + 1, mask, Graph, nflow);
  115. }
  116. }
  117. }
  118.  
  119. int main() {
  120. fin >> n >> m >> k >> q;
  121. Special.resize(k), Val.resize(k), Cut.assign(1 << k, 0), DP.assign(1 << k, 0);
  122. Dinic <int64_t> Graph(n, 0, n - 1);
  123. for(int i = 0; i < m; ++i) {
  124. fin >> u >> v >> w;
  125. --u, --v;
  126. if(i < k)
  127. Special[i] = make_pair(u, v);
  128. else
  129. if(w)
  130. Graph.addEdge(u, v, w);
  131. }
  132.  
  133. int64_t baseFlow = Graph.maxFlow();
  134. DFS(0, 0, Graph, baseFlow);
  135. for(int i = 1; i <= q; ++ i) {
  136. int64_t ans = Inf;
  137. for(int i = 0; i < k; ++ i)
  138. fin >> Val[i];
  139. for(int i = 0; i < k; ++ i)
  140. for(int j = 0; j < (1 << i); ++j)
  141. DP[j | (1 << i)] = DP[j] + Val[i];
  142. for(int i = 0; i < (1 << k); ++i)
  143. ans = min(ans, DP[i] + Cut[i]);
  144. fout << ans << "\n";
  145. }
  146. fin.close(), fout.close();
  147. return 0;
  148. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement