Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import java.util.*;
- import java.io.*;
- /**
- * MatroidIntersection was created by amir on 12.05.15.
- */
- public class A {
- FastScanner in;
- PrintWriter out;
- boolean systemIO = false;
- public class Edge {
- int b;
- int e;
- int color;
- int id;
- public Edge(int e, int b, int color, int id) {
- this.b = b;
- this.e = e;
- this.color = color;
- this.id = id;
- }
- public Edge reversedEdge() {
- return new Edge(b, e, color, id);
- }
- }
- int[] left;
- int[] used;
- int n, m;
- class DSU {
- int[] p;
- public DSU(int n) {
- p = new int[n];
- for (int i = 0; i < n; i++) {
- p[i] = i;
- }
- }
- void clear() {
- for (int i = 0; i < n; i++) {
- p[i] = i;
- }
- }
- int get(int x) {
- if (x == p[x]) {
- return x;
- }
- p[x] = get(p[x]);
- return p[x];
- }
- void union(int x, int y) {
- x = get(x);
- y = get(y);
- p[y] = x;
- }
- }
- public void solve() throws IOException {
- //long ttt = System.nanoTime();
- n = in.nextInt();
- m = in.nextInt();
- used = new int[n];
- Edge[] edges = new Edge[m];
- DSU dsu = new DSU(n);
- int[] col = new int[1000];
- left = new int[m];
- ArrayList<Integer> l = new ArrayList<Integer>();
- ArrayList<Integer> r = new ArrayList<Integer>();
- for (int i = 0; i < m; i++) {
- edges[i] = new Edge(in.nextInt() - 1, in.nextInt() - 1, in.nextInt() - 1, i);
- if (dsu.get(edges[i].b) != dsu.get(edges[i].e) && col[edges[i].color] == 0) {
- left[i] = 1;
- dsu.union(edges[i].b, edges[i].e);
- col[edges[i].color] = 1;
- l.add(i);
- } else {
- r.add(i);
- }
- }
- ArrayList<Integer>[] e2 = new ArrayList[m];
- for (int i = 0; i < m; i++) {
- e2[i] = new ArrayList<Integer>();
- }
- DSU d = new DSU(n);
- Queue<Integer> q = new ArrayDeque();
- int[] dist = new int[m];
- int[] prev = new int[m];
- int[] s1 = new int[m];
- int[] s2 = new int[m];
- //int ff = 0;
- while (true) {
- //ff++;
- //long zzz = System.nanoTime();
- for (int i = 0; i < m; i++) {
- e2[i].clear();
- }
- // left -> right
- for (int i : l) {
- for (int j : r) {
- if (edges[i].color == edges[j].color || col[edges[j].color] == 0) {
- e2[i].add(j);
- }
- }
- }
- //right -> left
- for (int j : l) {
- d.clear();
- for (int i : l) {
- if (i != j) {
- d.union(edges[i].b, edges[i].e);
- }
- }
- for (int i : r) {
- if (d.get(edges[i].b) != d.get(edges[i].e)) {
- e2[i].add(j);
- }
- }
- }
- //creating s1
- Arrays.fill(s1, 0);
- for (int i : r) {
- if (col[edges[i].color] == 0) {
- s1[i] = 1;
- }
- }
- //creating s2
- Arrays.fill(s2, 0);
- for (int i : r) {
- if (dsu.get(edges[i].b) != dsu.get(edges[i].e)) {
- s2[i] = 1;
- }
- }
- //finding shortest path between s1 and s2
- q.clear();
- Arrays.fill(dist, -1);
- Arrays.fill(prev, -1);
- for (int i = 0; i < m; i++) {
- if (s1[i] == 1) {
- q.add(i);
- dist[i] = 0;
- }
- }
- while (!q.isEmpty()) {
- int cur = q.poll();
- for (int x : e2[cur]) {
- if (dist[x] == -1) {
- dist[x] = dist[cur] + 1;
- prev[x] = cur;
- q.add(x);
- }
- }
- }
- int t = -1;
- for (int i = 0; i < m; i++) {
- if (s2[i] == 1 && dist[i] != -1 && (t == -1 || dist[t] > dist[i])) {
- t = i;
- }
- }
- if (t == -1) {
- break;
- }
- //recount left[]
- int k = 0;
- while (t != -1) {
- if (k % 2 == 0) {
- left[t] = 1;
- } else {
- left[t] = 0;
- }
- k++;
- t = prev[t];
- }
- // recount col[] and e[] and dsu
- Arrays.fill(col, 0);
- for (int i = 0; i < m; i++) {
- if (left[i] == 1) {
- col[edges[i].color] = 1;
- }
- }
- l.clear();
- r.clear();
- dsu.clear();
- for (int i = 0; i < m; i++) {
- if (left[i] == 1) {
- l.add(i);
- dsu.union(edges[i].b, edges[i].e);
- } else {
- r.add(i);
- }
- }
- //System.out.println(ff + " -- " + (System.nanoTime() - zzz) / 1000000);
- }
- int k = 0;
- for (int i = 0; i < m; i++) {
- k += left[i];
- }
- out.println(k);
- for (int i = 0; i < m; i++) {
- if (left[i] == 1) {
- out.print((i + 1) + " ");
- }
- }
- //System.out.println((System.nanoTime() - ttt) / 1000000);
- }
- public void run() {
- try {
- if (systemIO) {
- in = new FastScanner(System.in);
- out = new PrintWriter(System.out);
- } else {
- in = new FastScanner(new File("rainbow.in"));
- out = new PrintWriter(new File("rainbow.out"));
- }
- solve();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- class FastScanner {
- BufferedReader br;
- StringTokenizer st;
- FastScanner(File f) {
- try {
- br = new BufferedReader(new FileReader(f));
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- }
- }
- FastScanner(InputStream f) {
- br = new BufferedReader(new InputStreamReader(f));
- }
- String nextLine() {
- try {
- return br.readLine();
- } catch (IOException e) {
- return null;
- }
- }
- String next() {
- while (st == null || !st.hasMoreTokens()) {
- try {
- st = new StringTokenizer(br.readLine());
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- return st.nextToken();
- }
- int nextInt() {
- return Integer.parseInt(next());
- }
- long nextLong() {
- return Long.parseLong(next());
- }
- }
- public static void main(String[] arg) {
- new A().run();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement