// UVa 10158 - War import java.util.HashMap; import java.util.Map; import java.util.Scanner; public class Main { private static final int NOBODY = -1; private static UnionSet<Integer> unionSet; private static int[] enemyOf; public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); unionSet = new UnionSet<Integer>(); enemyOf = new int[n]; for (int i = 0; i < n; i++) { unionSet.makeSet(i); enemyOf[i] = NOBODY; } int codeOfTheOperation = scanner.nextInt(); int x = scanner.nextInt(); int y = scanner.nextInt(); while (codeOfTheOperation != 0) { switch (codeOfTheOperation) { case 1: if (areEnemies(x, y)) System.out.println(-1); else setFriends(x, y); break; case 2: if (areFriends(x, y)) System.out.println(-1); else setEnemies(x, y); break; case 3: System.out.println(areFriends(x, y) ? 1 : 0); break; case 4: System.out.println(areEnemies(x, y) ? 1 : 0); break; } codeOfTheOperation = scanner.nextInt(); x = scanner.nextInt(); y = scanner.nextInt(); } } private static void setFriends(int x, int y) { Integer rootX = unionSet.getRoot(x); Integer rootY = unionSet.getRoot(y); Integer enemyX = enemyOf[rootX]; Integer enemyY = enemyOf[rootY]; unionSet.union(x, y); Integer newRoot = unionSet.getRoot(rootX); if (enemyX != enemyY && enemyX != NOBODY && enemyY != NOBODY) { unionSet.union(enemyX, enemyY); Integer newEnemy = unionSet.getRoot(enemyX); enemyOf[newRoot] = newEnemy; } else if (enemyX != NOBODY) { enemyOf[newRoot] = enemyX; } else if (enemyY != NOBODY) { enemyOf[newRoot] = enemyY; } } private static void setEnemies(int x, int y) { Integer rootX = unionSet.getRoot(x); Integer rootY = unionSet.getRoot(y); Integer enemyX = enemyOf[rootX]; Integer enemyY = enemyOf[rootY]; if (enemyX == NOBODY) { enemyOf[rootX] = rootY; } if (enemyY == NOBODY) { enemyOf[rootY] = rootX; } if (enemyOf[rootX] == rootY && enemyOf[rootY] == rootX) return; if (enemyOf[rootX] != rootY) unionSet.union(enemyOf[rootX], rootY); if (enemyOf[rootY] != rootX) unionSet.union(enemyOf[rootY], rootX); } private static boolean areFriends(int x, int y) { return unionSet.areOnSameSet(x, y); } private static boolean areEnemies(int x, int y) { Integer rootX = unionSet.getRoot(x); Integer rootY = unionSet.getRoot(y); return enemyOf[rootX] == rootY; } private static class UnionSet<T> { private Map<T, UnionSetElement<T>> dataToElement = new HashMap<T, UnionSetElement<T>>(); public void makeSet(T data) { dataToElement.put(data, createElement(data)); } public void makeSets(Iterable<T> datas) { for (T data : datas) { dataToElement.put(data, createElement(data)); } } public boolean areOnSameSet(T x, T y) { UnionSetElement<T> xElement = dataToElement.get(x); UnionSetElement<T> yElement = dataToElement.get(y); return find(xElement) == find(yElement); } public T getRoot(T x) { UnionSetElement<T> element = dataToElement.get(x); UnionSetElement<T> root = find(element); return root.data; } public void union(T a, T b) { UnionSetElement<T> aElement = dataToElement.get(a); UnionSetElement<T> bElement = dataToElement.get(b); union(aElement, bElement); } private UnionSetElement<T> createElement(T data) { UnionSetElement<T> element = new UnionSetElement<T>(); element.parent = element; element.rank = 0; element.data = data; return element; } // i.e. getRoot private UnionSetElement<T> find(UnionSetElement<T> element) { if (element.parent != element) { element.parent = find(element.parent); } return element.parent; } private void union(UnionSetElement<T> x, UnionSetElement<T> y) { UnionSetElement<T> xRoot = find(x); UnionSetElement<T> yRoot = find(y); if (xRoot == yRoot) return; // x and y are not already in same set. Merge them. if (xRoot.rank < yRoot.rank) { xRoot.parent = yRoot; } else if (xRoot.rank > yRoot.rank) { yRoot.parent = xRoot; } else { yRoot.parent = xRoot; xRoot.rank = xRoot.rank + 1; } } private static class UnionSetElement<T> { public UnionSetElement<T> parent; public int rank; public T data; } } }
Monday, December 19, 2016
UVa 10158 - War
Subscribe to:
Post Comments (Atom)
No comments:
Post a Comment