Advertisement
qwerty787788

Flow decomposition

Nov 29th, 2012
222
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 4.20 KB | None | 0 0
  1. import java.io.*;
  2. import java.util.*;
  3.  
  4. public class Decomposition {
  5.     FastScanner in;
  6.     PrintWriter out;
  7.  
  8.     class Edge {
  9.         int fr, to;
  10.         int cost;
  11.         int id;
  12.         int flow;
  13.         Edge backEdge;
  14.  
  15.         public Edge(int fr, int to, int cost, int id) {
  16.             super();
  17.             this.fr = fr;
  18.             this.to = to;
  19.             this.cost = cost;
  20.             this.id = id;
  21.         }
  22.  
  23.     }
  24.  
  25.     ArrayList<Edge>[] g;
  26.     int[] d;
  27.     int[] last;
  28.     int n;
  29.  
  30.     boolean bfs() {
  31.         Arrays.fill(d, -1);
  32.         ArrayList<Integer> queue = new ArrayList<Integer>();
  33.         int it = 0;
  34.         queue.add(0);
  35.         d[0] = 0;
  36.         while (it < queue.size()) {
  37.             int v = queue.get(it);
  38.             for (Edge e : g[v]) {
  39.                 if (d[e.to] == -1 && e.flow < e.cost) {
  40.                     d[e.to] = d[v] + 1;
  41.                     queue.add(e.to);
  42.                 }
  43.             }
  44.             it++;
  45.         }
  46.         return d[n - 1] != -1;
  47.     }
  48.  
  49.     long dfs(int v, long flow) {
  50.         if (flow == 0 || v == n - 1)
  51.             return flow;
  52.         for (; last[v] < g[v].size(); last[v]++) {
  53.             Edge e = g[v].get(last[v]);
  54.             if (d[e.to] != d[v] + 1)
  55.                 continue;
  56.             long pushed = dfs(e.to, Math.min(flow, e.cost - e.flow));
  57.             if (pushed != 0) {
  58.                 e.flow += pushed;
  59.                 e.backEdge.flow -= pushed;
  60.                 return pushed;
  61.             }
  62.         }
  63.         return 0;
  64.     }
  65.  
  66.     boolean[] was;
  67.     ArrayList<Long> tmp = new ArrayList<Long>();
  68.  
  69.     long dfs2(int v, long flow) {
  70.         if (v == n - 1)
  71.             return flow;
  72.         was[v] = true;
  73.         for (Edge e : g[v]) {
  74.             if (e.flow > 0 && !was[e.to]) {
  75.                 tmp.add((long) e.id);
  76.                 long pushed = dfs2(e.to, Math.min(flow, e.flow));
  77.                 e.flow -= pushed;
  78.                 return pushed;
  79.             }
  80.         }
  81.         return 0;
  82.     }
  83.  
  84.     void solve() {
  85.         n = in.nextInt();
  86.         int m = in.nextInt();
  87.         g = new ArrayList[n];
  88.         for (int i = 0; i < n; i++)
  89.             g[i] = new ArrayList<Edge>();
  90.         for (int i = 0; i < m; i++) {
  91.             int fr = in.nextInt() - 1;
  92.             int to = in.nextInt() - 1;
  93.             int cost = in.nextInt();
  94.             Edge e1 = new Edge(fr, to, cost, i + 1);
  95.             Edge e2 = new Edge(to, fr, 0, i + 1);
  96.             e1.backEdge = e2;
  97.             e2.backEdge = e1;
  98.             g[fr].add(e1);
  99.             g[to].add(e2);
  100.         }
  101.         d = new int[n];
  102.         last = new int[n];
  103.         while (bfs()) {
  104.             while (true) {
  105.                 Arrays.fill(last, 0);
  106.                 long add = dfs(0, Long.MAX_VALUE);
  107.                 if (add == 0)
  108.                     break;
  109.             }
  110.         }
  111.         ArrayList<ArrayList<Long>> ans = new ArrayList<ArrayList<Long>>();
  112.         was = new boolean[n];
  113.         while (true) {
  114.             tmp = new ArrayList<Long>();
  115.             Arrays.fill(was, false);
  116.             long add = dfs2(0, Long.MAX_VALUE);
  117.             if (add == 0)
  118.                 break;
  119.             ans.add(tmp);
  120.             tmp.add(add);
  121.         }
  122.         out.println(ans.size());
  123.         for (int i = 0; i < ans.size(); i++) {
  124.             out.print(ans.get(i).get(ans.get(i).size() - 1) + " "
  125.                     + (ans.get(i).size() - 1) + " ");
  126.             for (int j = 0; j < ans.get(i).size() - 1; j++)
  127.                 out.print(ans.get(i).get(j) + " ");
  128.             out.println();
  129.         }
  130.     }
  131.  
  132.     void run() {
  133.         try {
  134.             in = new FastScanner(new File("decomposition.in"));
  135.             out = new PrintWriter(new File("decomposition.out"));
  136.  
  137.             solve();
  138.  
  139.             out.close();
  140.         } catch (FileNotFoundException e) {
  141.             e.printStackTrace();
  142.         }
  143.     }
  144.  
  145.     void runIO() {
  146.  
  147.         in = new FastScanner(System.in);
  148.         out = new PrintWriter(System.out);
  149.  
  150.         solve();
  151.  
  152.         out.close();
  153.     }
  154.  
  155.     class FastScanner {
  156.         BufferedReader br;
  157.         StringTokenizer st;
  158.  
  159.         public FastScanner(File f) {
  160.             try {
  161.                 br = new BufferedReader(new FileReader(f));
  162.             } catch (FileNotFoundException e) {
  163.                 e.printStackTrace();
  164.             }
  165.         }
  166.  
  167.         public FastScanner(InputStream f) {
  168.             br = new BufferedReader(new InputStreamReader(f));
  169.         }
  170.  
  171.         String next() {
  172.             while (st == null || !st.hasMoreTokens()) {
  173.                 String s = null;
  174.                 try {
  175.                     s = br.readLine();
  176.                 } catch (IOException e) {
  177.                     e.printStackTrace();
  178.                 }
  179.                 if (s == null)
  180.                     return null;
  181.                 st = new StringTokenizer(s);
  182.             }
  183.             return st.nextToken();
  184.         }
  185.  
  186.         boolean hasMoreTokens() {
  187.             while (st == null || !st.hasMoreTokens()) {
  188.                 String s = null;
  189.                 try {
  190.                     s = br.readLine();
  191.                 } catch (IOException e) {
  192.                     e.printStackTrace();
  193.                 }
  194.                 if (s == null)
  195.                     return false;
  196.                 st = new StringTokenizer(s);
  197.             }
  198.             return true;
  199.         }
  200.  
  201.         int nextInt() {
  202.             return Integer.parseInt(next());
  203.         }
  204.  
  205.         long nextLong() {
  206.             return Long.parseLong(next());
  207.         }
  208.     }
  209.  
  210.     public static void main(String[] args) {
  211.         new Decomposition().run();
  212.     }
  213. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement