Advertisement
Guest User

Untitled

a guest
Mar 29th, 2020
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.43 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.ArrayDeque;
  3. import java.util.Arrays;
  4. import java.util.StringTokenizer;
  5.  
  6. public class CountingStar {
  7. static class FastScanner {
  8. BufferedReader br;
  9. StringTokenizer st;
  10.  
  11. public FastScanner() {
  12. br = new BufferedReader(new InputStreamReader(System.in));
  13. }
  14.  
  15. String next() {
  16. while (st == null || !st.hasMoreElements()) {
  17. try {
  18. st = new StringTokenizer(br.readLine());
  19. } catch (IOException e) {
  20. e.printStackTrace();
  21. }
  22. }
  23. return st.nextToken();
  24. }
  25.  
  26. int nextInt() {
  27. return Integer.parseInt(next());
  28. }
  29.  
  30. long nextLong() {
  31. return Long.parseLong(next());
  32. }
  33. }
  34.  
  35. static class DirectedEdge {
  36. int from;
  37. int to;
  38. int c;
  39. int flow;
  40. DirectedEdge reversedEdge;
  41. boolean visited = false;
  42.  
  43. public DirectedEdge(int from, int to, int c) {
  44. this.from = from;
  45. this.to = to;
  46. this.c = c;
  47. this.flow = 0;
  48. reversedEdge = null;
  49. }
  50. }
  51.  
  52. static class Query {
  53. int a;
  54.  
  55.  
  56. int b;
  57.  
  58. public Query(int a, int b, int c) {
  59. this.a = a;
  60. this.b = b;
  61. this.c = c;
  62. }
  63.  
  64. int c;
  65.  
  66. }
  67.  
  68. static class Ship {
  69. int number;
  70.  
  71. public Ship(int number, int to) {
  72. this.number = number;
  73. this.to = to;
  74. }
  75.  
  76. int to;
  77. }
  78.  
  79. public static void main(String[] args) {
  80. FastScanner scanner = new FastScanner();
  81. int n = scanner.nextInt();
  82. int m = scanner.nextInt();
  83. int k = scanner.nextInt();
  84. int source1 = scanner.nextInt() - 1;
  85. int sink1 = scanner.nextInt() - 1;
  86. ArrayDeque<Integer>[] to1 = new ArrayDeque[n];
  87. for (int i = 0; i < n; i++) {
  88. to1[i] = new ArrayDeque<>();
  89. }
  90. for (int i = 0; i < m; i++) {
  91. int a = scanner.nextInt() - 1;
  92. int b = scanner.nextInt() - 1;
  93. to1[a].addLast(b);
  94. to1[b].addLast(a);
  95. }
  96. int L = shortestPath(to1, source1, sink1);
  97. ArrayDeque<Query> queries = new ArrayDeque<>();
  98.  
  99. for (int i = 0; i < (L + k - 1); i++) {
  100. for (int j = 0; j < n; j++) {
  101. queries.addLast(new Query(i * n + j, (i + 1) * n + j, Integer.MAX_VALUE));
  102. for (int to : to1[j]
  103. ) {
  104. queries.addLast(new Query(i * n + j, (i + 1) * n + to, 1));
  105. }
  106. }
  107. int level = i + 1;
  108. if (level >= L) {
  109. int source = source1;
  110. int sink = level * n + sink1;
  111. ArrayDeque<DirectedEdge>[] to = new ArrayDeque[level * n + n];
  112. for (int j = 0; j < to.length; j++) {
  113. to[j] = new ArrayDeque<>();
  114. }
  115. for (Query query : queries) {
  116. int a = query.a;
  117. int b = query.b;
  118. int c = query.c;
  119. DirectedEdge edge1 = new DirectedEdge(a, b, c);
  120. DirectedEdge reversedEdge1 = new DirectedEdge(b, a, 0);
  121. edge1.reversedEdge = reversedEdge1;
  122. reversedEdge1.reversedEdge = edge1;
  123. to[a].addLast(edge1);
  124. to[b].addLast(reversedEdge1);
  125. }
  126. boolean[] mark = new boolean[to.length];
  127. int maxFlow = 0;
  128. while (true) {
  129. Arrays.fill(mark, false);
  130. int delta = dfs(source, Integer.MAX_VALUE, mark, to, sink);
  131. if (delta > 0) {
  132. maxFlow += delta;
  133. if (maxFlow >= k) break;
  134. } else {
  135. break;
  136. }
  137. }
  138. if (maxFlow >= k) {
  139. System.out.println(level);
  140. ArrayDeque<Integer>[] shipsOnStar = new ArrayDeque[n];
  141. for (int j = 0; j < n; j++) {
  142. shipsOnStar[j] = new ArrayDeque<>();
  143. }
  144. for (int j = 0; j < k; j++) {
  145. shipsOnStar[source].addLast(j);
  146. }
  147. for (int curLevel = 0; curLevel < level; curLevel++) {
  148. ArrayDeque<Ship> ships = new ArrayDeque<>();
  149. for (int j = 0; j < n; j++) {
  150. for (DirectedEdge toEdge : to[curLevel * n + j]
  151. ) {
  152. if (toEdge.flow == 1 && toEdge.c != Integer.MAX_VALUE) {
  153. if (shipsOnStar[toEdge.from - n * (curLevel)].size() == 0) continue;
  154.  
  155. int shipLeft = shipsOnStar[toEdge.from - n * (curLevel)].removeFirst();
  156. ships.addLast(new Ship(shipLeft, toEdge.to - n * (curLevel + 1)));
  157. }
  158. }
  159. }
  160. System.out.print(ships.size());
  161. for (Ship ship : ships
  162. ) {
  163. shipsOnStar[ship.to].addLast(ship.number);
  164. System.out.print(" " + (ship.number + 1) + " " + (ship.to + 1));
  165. }
  166. System.out.print(System.lineSeparator());
  167. }
  168. break;
  169. }
  170.  
  171. }
  172.  
  173.  
  174. }
  175.  
  176.  
  177. }
  178.  
  179. private static int dfs(int v, int delta, boolean[] mark, ArrayDeque<DirectedEdge>[] to, int sink) {
  180. if (mark[v]) return 0;
  181. mark[v] = true;
  182. if (v == sink) return delta;
  183. for (DirectedEdge toEdge : to[v]
  184. ) {
  185. if (toEdge.flow < toEdge.c) {
  186. int deltaNew = dfs(toEdge.to, Math.min(delta, toEdge.c - toEdge.flow), mark, to, sink);
  187. if (deltaNew > 0) {
  188. toEdge.flow += deltaNew;
  189. toEdge.reversedEdge.flow = -toEdge.flow;
  190. return deltaNew;
  191. }
  192. }
  193. }
  194. return 0;
  195. }
  196.  
  197. private static int shortestPath(ArrayDeque<Integer>[] to1, int source1, int sink1) {
  198. ArrayDeque<Integer> arrayDeque = new ArrayDeque<>();
  199. boolean[] visited = new boolean[to1.length];
  200. arrayDeque.addLast(source1);
  201. visited[source1] = true;
  202. int[] from = new int[to1.length];
  203. Arrays.fill(from, -1);
  204. while (!arrayDeque.isEmpty()) {
  205. int cur = arrayDeque.removeFirst();
  206. for (int to : to1[cur]
  207. ) {
  208. if (!visited[to]) {
  209. visited[to] = true;
  210. arrayDeque.addLast(to);
  211. from[to] = cur;
  212. if (to == sink1) break;
  213. }
  214. }
  215. if (from[sink1] != -1) break;
  216. }
  217. if (from[sink1] == -1) return -1;
  218. int cur = sink1;
  219. int length = 0;
  220. while (cur != source1) {
  221. length++;
  222. cur = from[cur];
  223. }
  224. return length;
  225. }
  226. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement