Advertisement
VladNitu

dianaMaxFlowSlbz

Apr 24th, 2023
112
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 9.01 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 100000// maximum number of nodes in graph
  9. #define NMAX 100 + 5
  10. #define TMAX 1000 + 5
  11. using namespace std;
  12.  
  13. void __print(int x) { cerr << x; }
  14.  
  15. void __print(long x) { cerr << x; }
  16.  
  17. void __print(long long x) { cerr << x; }
  18.  
  19. void __print(unsigned x) { cerr << x; }
  20.  
  21. void __print(unsigned long x) { cerr << x; }
  22.  
  23. void __print(unsigned long long x) { cerr << x; }
  24.  
  25. void __print(float x) { cerr << x; }
  26.  
  27. void __print(double x) { cerr << x; }
  28.  
  29. void __print(long double x) { cerr << x; }
  30.  
  31. void __print(char x) { cerr << '\'' << x << '\''; }
  32.  
  33. void __print(const char *x) { cerr << '\"' << x << '\"'; }
  34.  
  35. void __print(const string &x) { cerr << '\"' << x << '\"'; }
  36.  
  37. void __print(bool x) { cerr << (x ? "true" : "false"); }
  38.  
  39. template<typename T, typename V, typename W>
  40. void __print(const std::tuple<T, V, W> &x) {
  41. cerr << '{';
  42. __print(std::get<0>(x));
  43. cerr << ',';
  44. __print(std::get<1>(x));
  45. cerr << ',';
  46. __print(std::get<2>(x));
  47. cerr << '}';
  48. }
  49.  
  50. template<typename T, typename V>
  51. void __print(const pair<T, V> &x) {
  52. cerr << '{';
  53. __print(x.first);
  54. cerr << ',';
  55. __print(x.second);
  56. cerr << '}';
  57. }
  58.  
  59. template<typename T>
  60. void __print(const T &x) {
  61. int f = 0;
  62. cerr << '{';
  63. for (auto &i: x) cerr << (f++ ? "," : ""), __print(i);
  64. cerr << "}";
  65. }
  66.  
  67. void _print() { cerr << "]\n"; }
  68.  
  69. template<typename T, typename... V>
  70. void _print(T t, V... v) {
  71. __print(t);
  72. if (sizeof...(v)) cerr << ", ";
  73. _print(v...);
  74. }
  75.  
  76. #ifndef ONLINE_JUDGE
  77. #define dbg(x...) cerr << "[" << #x << "] = ["; _print(x)
  78. #else
  79. #define dbg(x...)
  80. #endif
  81.  
  82.  
  83.  
  84. int n, m, k;
  85. int start, destination, weight;
  86. int startOfNewAgent;
  87. int vertex, steps, timeStamp;
  88.  
  89.  
  90. std::vector<int> agents;
  91. std::vector<std::vector<std::pair<int, int>>> targetPath;
  92.  
  93. // edges in the original graph
  94. int edges[NMAX][NMAX];
  95.  
  96. int viz[NMAX][TMAX];
  97.  
  98.  
  99. struct Edge
  100. {
  101. Edge(int _a, int _b, int _c, int _f, int _w) {
  102. a = _a; b = _b; c = _c; f = _f; w = _w;
  103. }
  104. ~Edge() { };
  105. int a; //from
  106. int b; //to
  107. int c; //capacity
  108. int f; //flow
  109. int w; //weight
  110. Edge* r;
  111. };
  112.  
  113.  
  114. const int MAX_DIST = 2000000; //do not choose INT_MAX because you are adding weights to it
  115. std::vector<Edge*> adj[MAXN];
  116. int distances[MAXN];
  117. Edge* parents[MAXN];
  118.  
  119. int nodecount;
  120. int source;
  121. int sink;
  122.  
  123. std::vector<std::vector<int>> layer_on_timestamp;
  124. std::vector<std::vector<int>> layer_on_double_timestamp;
  125. std::vector<int> sinks;
  126.  
  127. std::vector<int> possibleMakeSpan;
  128.  
  129. // bellman - ford
  130. bool find_path(int from, int to, std::vector<Edge*>& output)
  131. {
  132. std::fill(distances, distances+nodecount, MAX_DIST);
  133. std::fill(parents, parents+nodecount, (Edge*)0);
  134. distances[from] = 0;
  135.  
  136. bool updated = true;
  137. while(updated)
  138. {
  139. updated = false;
  140. for(int j = 0; j < nodecount; ++j)
  141. for(int k = 0; k < (int)adj[j].size(); ++k){
  142. Edge* e = adj[j][k];
  143. if( e->f >= e->c ) continue;
  144. if( distances[e->b] > distances[e->a] + e->w )
  145. {
  146. //std::cerr << distances[e->b] << " " << distances[e->a] << " " << e->w << std::endl;
  147. distances[e->b] = distances[e->a] + e->w;
  148. parents[e->b] = e;
  149. updated = true;
  150. }
  151. }
  152. }
  153. output.clear();
  154. if(distances[to] == MAX_DIST) return false;
  155. int cur = to;
  156. while(parents[cur])
  157. {
  158. output.push_back(parents[cur]);
  159. cur = parents[cur]->a;
  160. }
  161. return true;
  162. }
  163.  
  164. // MAX FLOW MIN COST IMPLEMENTATION
  165. int min_cost_max_flow(int source, int sink)
  166. {
  167. int total_cost = 0;
  168.  
  169. int totalFlow = 0;
  170. std::vector<Edge*> p;
  171. while(find_path(source, sink, p))
  172. {
  173. int flow = INT_MAX;
  174. for(int i = 0; i < p.size(); ++i)
  175. if(p[i]->c - p[i]->f < flow) flow = p[i]->c - p[i]->f;
  176.  
  177. int cost = 0;
  178. for(int i = 0; i < p.size(); ++i) {
  179. cost += p[i]->w;
  180. p[i]->f += flow;
  181. p[i]->r->f -= flow;
  182. }
  183. cost *= flow; //cost per flow
  184. total_cost += cost;
  185. totalFlow += flow;
  186. }
  187.  
  188. return total_cost;
  189. }
  190.  
  191. void add_edge(int a, int b, int c, int w)
  192. {
  193. Edge* e = new Edge(a, b, c, 0, w);
  194. Edge* re = new Edge(b, a, 0, 0, -w);
  195. e->r = re;
  196. re->r = e;
  197. adj[a].push_back(e);
  198. adj[b].push_back(re);
  199. }
  200.  
  201.  
  202. int main() {
  203. //std::ifstream cin("date.in");
  204. // freopen("date.in" , "r", stdin);
  205.  
  206. // read vertex num, edges num and k (agent/target count)
  207. std::cin >> n >> m >> k;
  208.  
  209. // read graph
  210. for(int i = 0; i < m; i++) {
  211. std::cin >> start >> destination >> weight;
  212.  
  213. // directed graph add just one time
  214. edges[start][destination] = weight;
  215. }
  216.  
  217. // see where the agents are starting -> value of index for each
  218. for(int i = 0; i < k; i++) {
  219. std::cin >> startOfNewAgent;
  220. agents.push_back(startOfNewAgent);
  221. }
  222.  
  223. // see the steps that each target makes -> (vertex, time)
  224. for(int i = 0; i < k; i++) {
  225. std::cin >> steps;
  226.  
  227. std::vector<std::pair<int, int>> path;
  228. for (int j = 0; j < steps; j++) {
  229. std::cin >> vertex >> timeStamp;
  230. path.push_back(std::make_pair(vertex, timeStamp));
  231.  
  232. }
  233.  
  234. targetPath.push_back(path);
  235. }
  236.  
  237. // construct graph
  238. source = 0;
  239. sink = 1;
  240.  
  241. int id = 2;
  242. int max_timestamp = 1000;
  243.  
  244. // create simple node layer
  245. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  246.  
  247. std::vector<int> node_at_timestamp;
  248. for(int i = 0; i < n ; i++) {
  249. node_at_timestamp.push_back(id);
  250. id ++;
  251. }
  252.  
  253. layer_on_timestamp.push_back(node_at_timestamp);
  254. }
  255.  
  256.  
  257. // create double node layer
  258. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  259.  
  260. std::vector<int> node_at_timestamp;
  261. for(int i = 0; i < n ; i++) {
  262. node_at_timestamp.push_back(id);
  263. id ++;
  264. }
  265.  
  266. layer_on_double_timestamp.push_back(node_at_timestamp);
  267. }
  268.  
  269. // create edges for each layer timestamp between node -> double node
  270. for(int timeStamp = 0 ; timeStamp < max_timestamp; timeStamp ++) {
  271. std::vector<int> initial = layer_on_timestamp[timeStamp];
  272. std::vector<int> doubled = layer_on_double_timestamp[timeStamp];
  273.  
  274. // add edges between the layers
  275. for(int i = 0; i < n; i++) {
  276. add_edge(initial[i], doubled[i], 1, 0);
  277. }
  278. }
  279.  
  280.  
  281.  
  282. // create the sink and the corresponding edges
  283. for(int target = 0; target < k; target ++) {
  284. sinks.push_back(id);
  285. // add edges to the sink from the target
  286. add_edge(sinks[target], sink, 1, 0);
  287. id++;
  288. }
  289.  
  290. // construct rest of the matrix
  291. std::queue<std::pair<int, int>> queue; // node, timestamp pair
  292.  
  293. // go through all the agents and create edges from the source
  294. for(int i = 0; i < k ; i++) {
  295. queue.push(std::make_pair(agents[i], 0));
  296. add_edge(source, layer_on_timestamp[0][agents[i]], 1, 0);
  297. }
  298.  
  299. while(!queue.empty()) {
  300. std::pair<int, int> current = queue.front();
  301. queue.pop();
  302.  
  303. int node = current.first;
  304. int timestamp = current.second;
  305.  
  306. if (timestamp > max_timestamp || viz[node][timestamp])
  307. continue;
  308.  
  309. viz[node][timestamp] = 1;
  310.  
  311.  
  312. // stay in place
  313. if(timestamp + 1 < max_timestamp) {
  314. add_edge(layer_on_double_timestamp[timestamp][node], layer_on_timestamp[timestamp + 1][node], 1,
  315. 1);
  316. queue.push(std::make_pair(node, timestamp + 1));
  317. }
  318.  
  319. for (int i = 0; i < n; i++) {
  320. int forward = edges[node][i];
  321.  
  322. if (timestamp + forward < max_timestamp && forward != 0) {
  323. add_edge(layer_on_double_timestamp[timestamp][node], layer_on_timestamp[timestamp + forward][i], 1,
  324. forward);
  325. queue.push(std::make_pair(i, timestamp + forward));
  326. }
  327. }
  328.  
  329. }
  330.  
  331. // create edges from targets to the sink target
  332. for(int target = 0; target < k; target ++) {
  333. int sink_of_target = sinks[target];
  334.  
  335. std::vector<std::pair<int, int>> path = targetPath[target];
  336.  
  337. // position -> vertex, timestamp
  338. for (auto position: path) {
  339. add_edge(layer_on_double_timestamp[position.second][position.first], sink_of_target, 1, 0);
  340. }
  341.  
  342. std::pair<int, int> last_node = path.back();
  343. for(int i = last_node.second + 1; i < max_timestamp; i++) {
  344. add_edge(layer_on_double_timestamp[i][last_node.first], sink_of_target, 1, 0);
  345. }
  346. }
  347.  
  348.  
  349. nodecount = id;
  350. std::cout << min_cost_max_flow(source, sink) << std::endl;
  351. }
  352.  
  353.  
  354.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement