Advertisement
VladNitu

minCostMaxFlow

Mar 30th, 2023
130
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.26 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. #define NMAX (int)(100)
  6. #define INF (int)(1e9)
  7. #define smallINF (int)(1e6) // avoid overflow: 25 * 25 * 1e6 <= INT_MAX
  8. #define ll long long
  9. #define mkp make_pair
  10. #define mkt make_tuple
  11. #define lsb(x) (x & -x)
  12. #define fo(i, n) for(int i=0,_n=(n);i<_n;i++)
  13.  
  14. void __print(int x) { cerr << x; }
  15.  
  16. void __print(long x) { cerr << x; }
  17.  
  18. void __print(long long x) { cerr << x; }
  19.  
  20. void __print(unsigned x) { cerr << x; }
  21.  
  22. void __print(unsigned long x) { cerr << x; }
  23.  
  24. void __print(unsigned long long x) { cerr << x; }
  25.  
  26. void __print(float x) { cerr << x; }
  27.  
  28. void __print(double x) { cerr << x; }
  29.  
  30. void __print(long double x) { cerr << x; }
  31.  
  32. void __print(char x) { cerr << '\'' << x << '\''; }
  33.  
  34. void __print(const char *x) { cerr << '\"' << x << '\"'; }
  35.  
  36. void __print(const string &x) { cerr << '\"' << x << '\"'; }
  37.  
  38. void __print(bool x) { cerr << (x ? "true" : "false"); }
  39.  
  40. template<typename T, typename V, typename W>
  41. void __print(const std::tuple<T, V, W> &x) {
  42. cerr << '{';
  43. __print(std::get<0>(x));
  44. cerr << ',';
  45. __print(std::get<1>(x));
  46. cerr << ',';
  47. __print(std::get<2>(x));
  48. cerr << '}';
  49. }
  50.  
  51. template<typename T, typename V>
  52. void __print(const pair<T, V> &x) {
  53. cerr << '{';
  54. __print(x.first);
  55. cerr << ',';
  56. __print(x.second);
  57. cerr << '}';
  58. }
  59.  
  60. template<typename T>
  61. void __print(const T &x) {
  62. int f = 0;
  63. cerr << '{';
  64. for (auto &i: x) cerr << (f++ ? "," : ""), __print(i);
  65. cerr << "}";
  66. }
  67.  
  68. void _print() { cerr << "]\n"; }
  69.  
  70. template<typename T, typename... V>
  71. void _print(T t, V... v) {
  72. __print(t);
  73. if (sizeof...(v)) cerr << ", ";
  74. _print(v...);
  75. }
  76.  
  77. #ifndef ONLINE_JUDGE
  78. #define dbg(x...) cerr << "[" << #x << "] = ["; _print(x)
  79. #else
  80. #define dbg(x...)
  81. #endif
  82.  
  83.  
  84.  
  85. int N, M, K, x, y, w, t;
  86. int source, sink;
  87. vector<vector<pair<int, int>>> G; // Directed graph, {neigh, time}
  88. vector<int> starts; // stores the starting node of each Agent
  89. vector<vector<pair<int, int>>> paths; // stores path of each Target
  90. vector<vector<int>> mat;
  91. vector<vector<int>> distances;
  92.  
  93. class Edge {
  94. public:
  95. Edge(int _a, int _b, int _c, int _f, int _w) {
  96. a = _a;
  97. b = _b;
  98. c = _c;
  99. f = _f;
  100. w = _w;
  101. }
  102.  
  103. ~Edge() {};
  104. int a; //from
  105. int b; //to
  106. int c; //capacity
  107. int f; //flow
  108. int w; //weight
  109. Edge *r;
  110.  
  111. };
  112.  
  113. class MaxFlowMinCost {
  114. public:
  115.  
  116.  
  117. static const int MAX_NODES = 100;
  118. const int MAX_DIST = 2000000; //do not choose INT_MAX because you are adding weights to it
  119. vector<vector<Edge *>> adj;
  120. int distances[MAX_NODES];
  121. Edge *parents[MAX_NODES];
  122. int node_count;
  123.  
  124. MaxFlowMinCost() { this->adj.resize(this->MAX_NODES);
  125. this->node_count = 2 * K + 2;
  126. }
  127.  
  128.  
  129. bool find_path(int from, int to, vector<Edge *> &output) // Assume no negative paths
  130. {
  131. fill(distances, distances + node_count, MAX_DIST);
  132. fill(parents, parents + node_count, (Edge *) 0);
  133. distances[from] = 0;
  134.  
  135. bool updated = true;
  136. while (updated) {
  137. updated = false;
  138. for (int j = 0; j < node_count; ++j)
  139. for (int k = 0; k < (int) adj[j].size(); ++k) {
  140. Edge *e = adj[j][k];
  141. if (e->f >= e->c) continue;
  142. if (distances[e->b] > distances[e->a] + e->w) {
  143. distances[e->b] = distances[e->a] + e->w;
  144. parents[e->b] = e;
  145. updated = true;
  146. }
  147. }
  148. }
  149. output.clear();
  150. if (distances[to] == MAX_DIST) return false;
  151. int cur = to;
  152. while (parents[cur]) {
  153. output.push_back(parents[cur]);
  154. cur = parents[cur]->a;
  155. }
  156. return true;
  157. }
  158.  
  159. int min_cost_max_flow(int source, int sink) {
  160. int total_cost = 0;
  161. vector<Edge *> p;
  162. while (find_path(source, sink, p)) {
  163. int flow = INT_MAX;
  164. for (int i = 0; i < p.size(); ++i)
  165. if (p[i]->c - p[i]->f < flow) flow = p[i]->c - p[i]->f;
  166.  
  167. int cost = 0;
  168. for (int i = 0; i < p.size(); ++i) {
  169. cost += p[i]->w;
  170. p[i]->f += flow;
  171. p[i]->r->f -= flow;
  172. }
  173. cost *= flow; //cost per flow
  174. total_cost += cost;
  175. }
  176. return total_cost;
  177. }
  178.  
  179. void add_edge(int a, int b, int c, int w) {
  180. Edge *e = new Edge(a, b, c, 0, w);
  181. Edge *re = new Edge(b, a, 0, 0, -w);
  182. e->r = re;
  183. re->r = e;
  184. adj[a].push_back(e);
  185. adj[b].push_back(re);
  186. }
  187.  
  188. int run(int source, int sink) {
  189. int ans = min_cost_max_flow(source, sink);
  190. for (int i = 0; i < node_count; ++i) {
  191. for (unsigned int j = 0; j < adj[i].size(); ++j)
  192. delete adj[i][j];
  193. adj[i].clear();
  194. }
  195.  
  196. return ans;
  197. }
  198. };
  199.  
  200.  
  201. vector<int> Dijkstra(int agentStart) {
  202. priority_queue<pair<int, int>, vector<pair<int, int> >, greater<> > h;
  203.  
  204. bitset<300> viz;
  205.  
  206. vector<int> d(N + 1);
  207. for (int i = 0; i < N; ++i) d[i] = INT_MAX;
  208. d[agentStart] = 0;
  209.  
  210. h.push({0, agentStart});
  211. while (!h.empty()) {
  212. int node = h.top().second;
  213. h.pop();
  214. int lg = G[node].size();
  215. if (!viz[node])
  216. for (int i = 0; i < lg; ++i) {
  217. int vec = G[node][i].first;
  218. if (d[vec] > d[node] + G[node][i].second) {
  219. d[vec] = d[node] + G[node][i].second;
  220. h.push({d[vec], vec});
  221. }
  222.  
  223. }
  224.  
  225. viz[node] = true;
  226. }
  227.  
  228. return d;
  229. }
  230.  
  231. void read() {
  232. cin >> N >> M >> K;
  233. G.resize(N + 1);
  234. for (int i = 0; i < M; ++i) {
  235. cin >> x >> y >> w;
  236. G[x].push_back({y, w});
  237. }
  238.  
  239. int pathLength;
  240. vector<pair<int, int>> path;
  241.  
  242. starts.resize(K);
  243. for (int i = 0; i < K; ++i) {
  244. cin >> starts[i];
  245. }
  246.  
  247. for (int x = 0; x < K; ++x) {
  248. cin >> pathLength;
  249. path.resize(pathLength);
  250.  
  251. for (int j = 0; j < pathLength; ++j) {
  252. cin >> y >> t;
  253. path[j] = {y, t};
  254.  
  255. }
  256.  
  257. paths.push_back(path);
  258. }
  259. }
  260.  
  261. void runDijkstraOnEachAgent() {
  262. distances.clear();
  263. for (int agentId = 0; agentId < K; ++agentId) {
  264. int agentStart = starts[agentId];
  265. distances.push_back(Dijkstra(agentStart));
  266. }
  267. }
  268.  
  269. void constructMatrix() {
  270. mat.resize(K);
  271. for (int agentId = 0; agentId < K; ++agentId) {
  272. mat[agentId].resize(K);
  273. const vector<int> &distance = distances[agentId];
  274. for (int targetId = 0; targetId < K; ++targetId) {
  275. mat[agentId][targetId] = smallINF;
  276. for (pair<int, int> &path: paths[targetId]) {
  277. int node = path.first;
  278. int time = path.second;
  279. if (distance[node] <=
  280. time) // If agent reaches this note before or at the same time with target -> consider as possible sol EDGE - target waits in the last node on its path
  281. mat[agentId][targetId] = min(mat[agentId][targetId], time);
  282. }
  283.  
  284. }
  285. }
  286. }
  287.  
  288.  
  289. MaxFlowMinCost *constructFlowGraph() {
  290.  
  291. source = 2 * K;
  292. sink = 2 * K + 1;
  293. MaxFlowMinCost *maxFlowMinCost = new MaxFlowMinCost();
  294.  
  295. for (int agentId = 0; agentId < K; ++agentId)
  296. maxFlowMinCost->add_edge(source, agentId, 1, 0);
  297. for (int targetId = K; targetId < 2 * K; ++targetId)
  298. maxFlowMinCost->add_edge(targetId, sink, 1, 0);
  299.  
  300. for (int agentId = 0; agentId < K; ++agentId)
  301. for (int targetId = K; targetId < 2 * K; ++targetId)
  302. maxFlowMinCost->add_edge(agentId, targetId, 1, mat[agentId][targetId - K]);
  303.  
  304. return maxFlowMinCost;
  305.  
  306. }
  307.  
  308. int main() {
  309.  
  310. // freopen("../cmac/mincost/small-sparse-1.in", "r", stdin);
  311. // freopen("../cmac/mincost/small-sparse-1.out", "w", stdout);
  312.  
  313. read();
  314. runDijkstraOnEachAgent();
  315. constructMatrix();
  316.  
  317. MaxFlowMinCost *maxFlowMinCost = constructFlowGraph();
  318.  
  319. int minCost = maxFlowMinCost->run(source, sink);
  320. cout << minCost << '\n';
  321.  
  322. return 0;
  323. }
  324.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement