Advertisement
VladNitu

maxFlowDiana

Apr 24th, 2023
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.34 KB | None | 0 0
  1. #include <iostream>
  2. #include <vector>
  3. #include <queue>
  4. #include <climits>
  5. #include <algorithm>
  6. #include <fstream>
  7.  
  8. #define MAXN 1000000// maximum number of nodes in graph
  9. #define NMAX 100 + 5
  10. #define TMAX 1000 + 5
  11. #define INF 1000000
  12. using namespace std;
  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;
  86. int start, destination, weight;
  87. int startOfNewAgent;
  88. int vertex, steps, timeStamp;
  89.  
  90.  
  91. std::vector<int> agents;
  92. std::vector<std::vector<std::pair<int, int>>> targetPath;
  93.  
  94. // edges in the original graph
  95. int edges[NMAX][NMAX];
  96.  
  97. int viz[NMAX][TMAX];
  98.  
  99.  
  100.  
  101. struct Edge
  102. {
  103. Edge(int _a, int _b, int _c, int _f, int _w) {
  104. a = _a; b = _b; c = _c; f = _f; w = _w;
  105. }
  106. ~Edge() { };
  107. int a; //from
  108. int b; //to
  109. int c; //capacity
  110. int f; //flow
  111. int w; //weight
  112. Edge* r;
  113. };
  114.  
  115. void restartAndFillInMatrixBinary(int matrix[2000][2000], int mid);
  116.  
  117. void constructPossibleSpans();
  118.  
  119. const int MAX_DIST = 2000000; //do not choose INT_MAX because you are adding weights to it
  120. std::vector<Edge*> adj[MAXN];
  121. int distances[MAXN];
  122. Edge* parents[MAXN];
  123.  
  124. int nodecount;
  125. int source;
  126. int sink;
  127.  
  128. std::vector<std::vector<int>> layer_on_timestamp;
  129. std::vector<std::vector<int>> layer_on_double_timestamp;
  130. std::vector<int> sinks;
  131.  
  132. std::vector<int> possibleMakeSpan;
  133.  
  134. // bellman - ford
  135. bool find_path(int from, int to, std::vector<Edge*>& output)
  136. {
  137. std::fill(distances, distances+nodecount, MAX_DIST);
  138. std::fill(parents, parents+nodecount, (Edge*)0);
  139. distances[from] = 0;
  140.  
  141. bool updated = true;
  142. while(updated)
  143. {
  144. updated = false;
  145. for(int j = 0; j < nodecount; ++j)
  146. for(int k = 0; k < (int)adj[j].size(); ++k){
  147. Edge* e = adj[j][k];
  148. if( e->f >= e->c ) continue;
  149. if( distances[e->b] > distances[e->a] + e->w )
  150. {
  151. //std::cerr << distances[e->b] << " " << distances[e->a] << " " << e->w << std::endl;
  152. distances[e->b] = distances[e->a] + e->w;
  153. parents[e->b] = e;
  154. updated = true;
  155. }
  156. }
  157. }
  158. output.clear();
  159. if(distances[to] == MAX_DIST) return false;
  160. int cur = to;
  161. while(parents[cur])
  162. {
  163. output.push_back(parents[cur]);
  164. cur = parents[cur]->a;
  165. }
  166. return true;
  167. }
  168.  
  169. // MAX FLOW MIN COST IMPLEMENTATION
  170. int min_cost_max_flow(int source, int sink)
  171. {
  172. int total_cost = 0;
  173.  
  174. int totalFlow = 0;
  175. std::vector<Edge*> p;
  176. while(find_path(source, sink, p))
  177. {
  178. int flow = INT_MAX;
  179. for(int i = 0; i < p.size(); ++i)
  180. if(p[i]->c - p[i]->f < flow) flow = p[i]->c - p[i]->f;
  181.  
  182. int cost = 0;
  183. for(int i = 0; i < p.size(); ++i) {
  184. cost += p[i]->w;
  185. p[i]->f += flow;
  186. p[i]->r->f -= flow;
  187. }
  188. cost *= flow; //cost per flow
  189. total_cost += cost;
  190. totalFlow += flow;
  191. }
  192.  
  193. return total_cost;
  194. }
  195.  
  196. void add_edge(int a, int b, int c, int w)
  197. {
  198. Edge* e = new Edge(a, b, c, 0, w);
  199. Edge* re = new Edge(b, a, 0, 0, -w);
  200. e->r = re;
  201. re->r = e;
  202. adj[a].push_back(e);
  203. adj[b].push_back(re);
  204. }
  205.  
  206.  
  207. int main() {
  208. //std::ifstream cin("date.in");
  209. // freopen("date.in" , "r", stdin);
  210.  
  211. // read vertex num, edges num and k (agent/target count)
  212. std::cin >> n >> m >> k;
  213.  
  214. // read graph
  215. for(int i = 0; i < m; i++) {
  216. std::cin >> start >> destination >> weight;
  217.  
  218. // directed graph add just one time
  219. edges[start][destination] = weight;
  220. }
  221.  
  222. // see where the agents are starting -> value of index for each
  223. for(int i = 0; i < k; i++) {
  224. std::cin >> startOfNewAgent;
  225. agents.push_back(startOfNewAgent);
  226. }
  227.  
  228. // see the steps that each target makes -> (vertex, time)
  229. for(int i = 0; i < k; i++) {
  230. std::cin >> steps;
  231.  
  232. std::vector<std::pair<int, int>> path;
  233. for (int j = 0; j < steps; j++) {
  234. std::cin >> vertex >> timeStamp;
  235. path.push_back(std::make_pair(vertex, timeStamp));
  236.  
  237. }
  238.  
  239. targetPath.push_back(path);
  240. }
  241.  
  242. // construct graph
  243. source = 0;
  244. sink = 1;
  245.  
  246. int id = 2;
  247. int max_timestamp = 500;
  248.  
  249. // create simple node layer
  250. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  251.  
  252. std::vector<int> node_at_timestamp;
  253. for(int i = 0; i < n ; i++) {
  254. node_at_timestamp.push_back(id);
  255. id ++;
  256. }
  257.  
  258. layer_on_timestamp.push_back(node_at_timestamp);
  259. }
  260.  
  261.  
  262. // create double node layer
  263. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  264.  
  265. std::vector<int> node_at_timestamp;
  266. for(int i = 0; i < n ; i++) {
  267. node_at_timestamp.push_back(id);
  268. id ++;
  269. }
  270.  
  271. layer_on_double_timestamp.push_back(node_at_timestamp);
  272. }
  273.  
  274. // create edges for each layer timestamp between node -> double node
  275. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  276. std::vector<int> initial = layer_on_timestamp[timeStamp];
  277. std::vector<int> doubled = layer_on_double_timestamp[timeStamp];
  278.  
  279. // add edges between the layers
  280. for(int i = 0; i < n; i++) {
  281. add_edge(initial[i], doubled[i], 1, 0);
  282. }
  283. }
  284.  
  285.  
  286.  
  287. // create the sink and the corresponding edges
  288. for(int target = 0; target < k; target ++) {
  289. sinks.push_back(id);
  290. // add edges to the sink from the target
  291. add_edge(sinks[target], sink, 1, 0);
  292. id++;
  293. }
  294.  
  295. // construct rest of the matrix
  296. std::queue<std::pair<int, int>> queue; // node, timestamp pair
  297.  
  298. // go through all the agents and create edges from the source
  299. for(int i = 0; i < k ; i++) {
  300. // add location for all agents
  301. queue.push(std::make_pair(agents[i], 0));
  302.  
  303. // add edge from source
  304.  
  305. add_edge(source, layer_on_timestamp[0][agents[i]], 1, 0);
  306. }
  307.  
  308. while(!queue.empty()) {
  309. std::pair<int, int> current = queue.front();
  310. queue.pop();
  311.  
  312. int node = current.first;
  313. int timestamp = current.second;
  314.  
  315. if (viz[node][timestamp] || timestamp > max_timestamp)
  316. continue;
  317.  
  318. viz[node][timestamp] = 1;
  319.  
  320. // std::cout << node << " " << timestamp << std::endl;
  321.  
  322. // stay in place
  323. if(timestamp + 1 < max_timestamp && viz[node][timestamp + 1] == 0) {
  324. add_edge(layer_on_double_timestamp[timestamp][node], layer_on_timestamp[timestamp + 1][node], 1,
  325. 1);
  326. queue.push(std::make_pair(node, timestamp + 1));
  327. }
  328.  
  329. for (int i = 0; i < n; i++) {
  330. int forward = edges[node][i];
  331.  
  332. if (timestamp + forward < max_timestamp && viz[i][timestamp + forward] == 0 && forward != 0) {
  333. add_edge(layer_on_double_timestamp[timestamp][node], layer_on_timestamp[timestamp + forward][i], 1,
  334. forward);
  335. queue.push(std::make_pair(i, timestamp + forward));
  336. }
  337. }
  338.  
  339. }
  340.  
  341. // create edges from targets to the sink target
  342. for(int target = 0; target < k; target ++) {
  343. int sink_of_target = sinks[target];
  344.  
  345. std::vector<std::pair<int, int>> path = targetPath[target];
  346.  
  347. // position -> vertex, timestamp
  348. for (auto position: path) {
  349. add_edge(layer_on_double_timestamp[position.second][position.first], sink_of_target, 1, 0);
  350. }
  351.  
  352. std::pair<int, int> last_node = path.back();
  353. for(int i = last_node.second + 1; i < max_timestamp; i++) {
  354. add_edge(layer_on_double_timestamp[i][last_node.first], sink_of_target, 1, 0);
  355. }
  356. }
  357.  
  358.  
  359. nodecount = id;
  360. std::cout << min_cost_max_flow(source, sink) << std::endl;
  361. }
  362.  
  363.  
  364.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement