Advertisement
Guest User

Untitled

a guest
May 25th, 2015
271
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.70 KB | None | 0 0
  1.  
  2. import java.util.*;
  3. import java.io.*;
  4.  
  5. /**
  6.  * MatroidIntersection was created by amir on 12.05.15.
  7.  */
  8.  
  9. public class A {
  10.     FastScanner in;
  11.     PrintWriter out;
  12.     boolean systemIO = false;
  13.  
  14.     public class Edge {
  15.         int b;
  16.         int e;
  17.         int color;
  18.         int id;
  19.  
  20.         public Edge(int e, int b, int color, int id) {
  21.             this.b = b;
  22.             this.e = e;
  23.             this.color = color;
  24.             this.id = id;
  25.         }
  26.  
  27.         public Edge reversedEdge() {
  28.             return new Edge(b, e, color, id);
  29.         }
  30.  
  31.     }
  32.  
  33.     int[] left;
  34.     int[] used;
  35.     int n, m;
  36.  
  37.  
  38.  
  39.     class DSU {
  40.         int[] p;
  41.  
  42.         public DSU(int n) {
  43.             p = new int[n];
  44.             for (int i = 0; i < n; i++) {
  45.                 p[i] = i;
  46.             }
  47.         }
  48.  
  49.         void clear() {
  50.             for (int i = 0; i < n; i++) {
  51.                 p[i] = i;
  52.             }
  53.         }
  54.  
  55.         int get(int x) {
  56.             if (x == p[x]) {
  57.                 return x;
  58.             }
  59.             p[x] = get(p[x]);
  60.             return p[x];
  61.         }
  62.  
  63.         void union(int x, int y) {
  64.             x = get(x);
  65.             y = get(y);
  66.             p[y] = x;
  67.         }
  68.  
  69.     }
  70.  
  71.     public void solve() throws IOException {
  72.         //long ttt = System.nanoTime();
  73.         n = in.nextInt();
  74.         m = in.nextInt();
  75.         used = new int[n];
  76.         Edge[] edges = new Edge[m];
  77.         DSU dsu = new DSU(n);
  78.         int[] col = new int[1000];
  79.         left = new int[m];
  80.         ArrayList<Integer> l = new ArrayList<Integer>();
  81.         ArrayList<Integer> r = new ArrayList<Integer>();
  82.  
  83.         for (int i = 0; i < m; i++) {
  84.             edges[i] = new Edge(in.nextInt() - 1, in.nextInt() - 1, in.nextInt() - 1, i);
  85.             if (dsu.get(edges[i].b) != dsu.get(edges[i].e) && col[edges[i].color] == 0) {
  86.                 left[i] = 1;
  87.                 dsu.union(edges[i].b, edges[i].e);
  88.                 col[edges[i].color] = 1;
  89.                 l.add(i);
  90.             } else {
  91.                 r.add(i);
  92.             }
  93.         }
  94.  
  95.         ArrayList<Integer>[] e2 = new ArrayList[m];
  96.         for (int i = 0; i < m; i++) {
  97.             e2[i] = new ArrayList<Integer>();
  98.         }
  99.  
  100.         DSU d = new DSU(n);
  101.         Queue<Integer> q = new ArrayDeque();
  102.         int[] dist = new int[m];
  103.         int[] prev = new int[m];
  104.         int[] s1 = new int[m];
  105.         int[] s2 = new int[m];
  106.  
  107.         //int ff = 0;
  108.         while (true) {
  109.             //ff++;
  110.             //long zzz = System.nanoTime();
  111.             for (int i = 0; i < m; i++) {
  112.                 e2[i].clear();
  113.             }
  114.  
  115.             // left -> right
  116.  
  117.             for (int i : l) {
  118.                 for (int j : r) {
  119.                     if (edges[i].color == edges[j].color || col[edges[j].color] == 0) {
  120.                         e2[i].add(j);
  121.                     }
  122.                 }
  123.             }
  124.  
  125.             //right -> left
  126.  
  127.             for (int j : l) {
  128.                 d.clear();
  129.                 for (int i : l) {
  130.                     if (i != j) {
  131.                         d.union(edges[i].b, edges[i].e);
  132.                     }
  133.                 }
  134.                 for (int i : r) {
  135.                     if (d.get(edges[i].b) != d.get(edges[i].e)) {
  136.                         e2[i].add(j);
  137.                     }
  138.                 }
  139.             }
  140.  
  141.             //creating s1
  142.  
  143.             Arrays.fill(s1, 0);
  144.             for (int i : r) {
  145.                 if (col[edges[i].color] == 0) {
  146.                     s1[i] = 1;
  147.                 }
  148.             }
  149.  
  150.             //creating s2
  151.  
  152.             Arrays.fill(s2, 0);
  153.             for (int i : r) {
  154.                 if (dsu.get(edges[i].b) != dsu.get(edges[i].e)) {
  155.                     s2[i] = 1;
  156.                 }
  157.             }
  158.  
  159.             //finding shortest path between s1 and s2
  160.  
  161.             q.clear();
  162.             Arrays.fill(dist, -1);
  163.             Arrays.fill(prev, -1);
  164.             for (int i = 0; i < m; i++) {
  165.                 if (s1[i] == 1) {
  166.                     q.add(i);
  167.                     dist[i] = 0;
  168.                 }
  169.             }
  170.             while (!q.isEmpty()) {
  171.                 int cur = q.poll();
  172.                 for (int x : e2[cur]) {
  173.                     if (dist[x] == -1) {
  174.                         dist[x] = dist[cur] + 1;
  175.                         prev[x] = cur;
  176.                         q.add(x);
  177.                     }
  178.                 }
  179.             }
  180.  
  181.             int t = -1;
  182.             for (int i = 0; i < m; i++) {
  183.                 if (s2[i] == 1 && dist[i] != -1 && (t == -1 || dist[t] > dist[i])) {
  184.                     t = i;
  185.                 }
  186.             }
  187.  
  188.             if (t == -1) {
  189.                 break;
  190.             }
  191.  
  192.             //recount left[]
  193.  
  194.             int k = 0;
  195.             while (t != -1) {
  196.                 if (k % 2 == 0) {
  197.                     left[t] = 1;
  198.                 } else {
  199.                     left[t] = 0;
  200.                 }
  201.                 k++;
  202.                 t = prev[t];
  203.             }
  204.  
  205.             // recount col[] and e[] and dsu
  206.             Arrays.fill(col, 0);
  207.             for (int i = 0; i < m; i++) {
  208.                 if (left[i] == 1) {
  209.                     col[edges[i].color] = 1;
  210.                 }
  211.             }
  212.  
  213.              l.clear();
  214.             r.clear();
  215.             dsu.clear();
  216.             for (int i = 0; i < m; i++) {
  217.                 if (left[i] == 1) {
  218.                     l.add(i);
  219.                     dsu.union(edges[i].b, edges[i].e);
  220.                  } else {
  221.                     r.add(i);
  222.                 }
  223.             }
  224.             //System.out.println(ff + "  --  " + (System.nanoTime() - zzz) / 1000000);
  225.         }
  226.  
  227.  
  228.         int k = 0;
  229.         for (int i = 0; i < m; i++) {
  230.             k += left[i];
  231.         }
  232.         out.println(k);
  233.         for (int i = 0; i < m; i++) {
  234.             if (left[i] == 1) {
  235.                 out.print((i + 1) + " ");
  236.             }
  237.         }
  238.         //System.out.println((System.nanoTime() - ttt) / 1000000);
  239.     }
  240.  
  241.     public void run() {
  242.         try {
  243.             if (systemIO) {
  244.                 in = new FastScanner(System.in);
  245.                 out = new PrintWriter(System.out);
  246.             } else {
  247.                 in = new FastScanner(new File("rainbow.in"));
  248.                 out = new PrintWriter(new File("rainbow.out"));
  249.             }
  250.             solve();
  251.  
  252.             out.close();
  253.         } catch (IOException e) {
  254.             e.printStackTrace();
  255.         }
  256.     }
  257.  
  258.     class FastScanner {
  259.         BufferedReader br;
  260.         StringTokenizer st;
  261.  
  262.  
  263.         FastScanner(File f) {
  264.             try {
  265.                 br = new BufferedReader(new FileReader(f));
  266.             } catch (FileNotFoundException e) {
  267.                 e.printStackTrace();
  268.             }
  269.         }
  270.  
  271.         FastScanner(InputStream f) {
  272.             br = new BufferedReader(new InputStreamReader(f));
  273.         }
  274.  
  275.         String nextLine() {
  276.             try {
  277.                 return br.readLine();
  278.             } catch (IOException e) {
  279.                 return null;
  280.             }
  281.         }
  282.  
  283.         String next() {
  284.             while (st == null || !st.hasMoreTokens()) {
  285.                 try {
  286.                     st = new StringTokenizer(br.readLine());
  287.                 } catch (IOException e) {
  288.                     e.printStackTrace();
  289.                 }
  290.             }
  291.             return st.nextToken();
  292.         }
  293.  
  294.         int nextInt() {
  295.             return Integer.parseInt(next());
  296.         }
  297.  
  298.         long nextLong() {
  299.             return Long.parseLong(next());
  300.         }
  301.  
  302.     }
  303.  
  304.     public static void main(String[] arg) {
  305.         new A().run();
  306.     }
  307. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement