153 lines
3.2 KiB
Java
153 lines
3.2 KiB
Java
package chelper;
|
|
|
|
import java.util.ArrayList;
|
|
import java.util.Collections;
|
|
import java.util.HashSet;
|
|
import java.util.Set;
|
|
import java.util.TreeSet;
|
|
|
|
import io.InputReader;
|
|
import io.OutputWriter;
|
|
|
|
|
|
public class Sazanka2J {
|
|
|
|
class Edge {
|
|
|
|
int a, b;
|
|
|
|
Edge(int a, int b) {
|
|
this.a = a;
|
|
this.b = b;
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if (this == o) {
|
|
return true;
|
|
}
|
|
if (!(o instanceof Edge)) {
|
|
return false;
|
|
}
|
|
|
|
Edge edge = (Edge) o;
|
|
|
|
if (a != edge.a) {
|
|
return false;
|
|
}
|
|
return b == edge.b;
|
|
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
int result = a;
|
|
result = 31 * result + b;
|
|
return result;
|
|
}
|
|
}
|
|
|
|
ArrayList<Integer>[] leftToRightEdges;
|
|
boolean[][] graphToLeft;
|
|
boolean[][] graphToRight;
|
|
boolean[] usedLeft;
|
|
boolean[] usedRight;
|
|
int m, n;
|
|
|
|
void dfs(int x, boolean left) {
|
|
// System.out.println("dfs run " + x + " " + left);
|
|
if (left) {
|
|
usedLeft[x] = true;
|
|
for (int i = 0; i < n; i++) {
|
|
if (graphToRight[x][i] && !usedRight[i]) {
|
|
dfs(i, false);
|
|
}
|
|
}
|
|
} else {
|
|
usedRight[x] = true;
|
|
for (int i = 0; i < m; i++) {
|
|
if (graphToLeft[x][i] && !usedLeft[i]) {
|
|
dfs(i, true);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public void solve(int testNumber, InputReader in, OutputWriter out) {
|
|
m = in.nextInt();
|
|
n = in.nextInt();
|
|
|
|
leftToRightEdges = new ArrayList[m];
|
|
for (int i = 0; i < m; i++) {
|
|
leftToRightEdges[i] = new ArrayList<>();
|
|
int k = in.nextInt();
|
|
for (int j = 0; j < k; j++) {
|
|
leftToRightEdges[i].add(in.nextInt() - 1);
|
|
}
|
|
}
|
|
|
|
boolean[] nasucsh = new boolean[m];
|
|
Set<Edge> parsoch = new HashSet<>();
|
|
for (int i = 0; i < m; i++) {
|
|
int x = in.nextInt();
|
|
if (x > 0) {
|
|
parsoch.add(new Edge(i, x - 1));
|
|
nasucsh[i] = true;
|
|
}
|
|
}
|
|
|
|
graphToLeft = new boolean[n][m];
|
|
graphToRight = new boolean[m][n];
|
|
for (int i = 0; i < m; i++) {
|
|
for (int j : leftToRightEdges[i]) {
|
|
if (parsoch.contains(new Edge(i, j))) {
|
|
graphToLeft[j][i] = true;
|
|
// System.out.println("toleft " + j + " " + i);
|
|
} else {
|
|
graphToRight[i][j] = true;
|
|
// System.out.println("toright " + i + " " + j);
|
|
}
|
|
}
|
|
}
|
|
|
|
usedLeft = new boolean[m];
|
|
usedRight = new boolean[n];
|
|
for (int i = 0; i < m; i++) {
|
|
if (!nasucsh[i]) {
|
|
// out.println("dfs " + i);
|
|
dfs(i, true);
|
|
}
|
|
}
|
|
|
|
ArrayList<Integer> answerLeft = new ArrayList<>();
|
|
ArrayList<Integer> answerRight = new ArrayList<>();
|
|
|
|
Collections.sort(answerLeft);
|
|
Collections.sort(answerRight);
|
|
|
|
|
|
for (int i = 0; i < m; i++) {
|
|
if (!usedLeft[i]) {
|
|
answerLeft.add(i);
|
|
}
|
|
}
|
|
for (int i = 0; i < n; i++) {
|
|
if (usedRight[i]) {
|
|
answerRight.add(i);
|
|
}
|
|
}
|
|
|
|
out.println(answerLeft.size() + answerRight.size());
|
|
|
|
out.print(answerLeft.size() + " ");
|
|
for (int i : answerLeft) {
|
|
out.print(i + 1 + " ");
|
|
}
|
|
out.println();
|
|
out.print(answerRight.size() + " ");
|
|
for (int i : answerRight) {
|
|
out.print(i + 1 + " ");
|
|
}
|
|
}
|
|
}
|