Pagini recente » Cod sursa (job #269581) | Cod sursa (job #2958318) | Cod sursa (job #3265391) | Cod sursa (job #618116) | Cod sursa (job #3227383)
/*
* TODO
*
* Complexity: O(V + E), where V is the number of vertices
* E is the number of edges.
*/
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.Reader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.Stack;
import java.util.StringTokenizer;
public class Main {
public static void main(final String[] args) throws IOException {
try (var std = new InOut("party.in", "party.out")) {
var vars = std.in.nextInt();
var conds = std.in.nextInt();
var graph = new Graph(vars);
for (var i = 0; i < conds; i += 1) {
var a = std.in.nextInt();
var b = std.in.nextInt();
var type = std.in.nextInt();
if (type == 0) {
graph.imply(-a, b);
} else if (type == 1) {
graph.imply(-a, -b);
} else if (type == 2) {
graph.imply(-b, -a);
} else if (type == 3) {
graph.imply(a, -b);
}
}
var res = solve(graph);
std.out.println(res.size());
for (var index : res) {
std.out.println(index);
}
}
}
private static class Node {
public Set<Integer> edges = new HashSet<>();
public int low = -1;
public int time = -1;
public boolean inStack = false;
public Boolean assignment = null;
}
private static class Graph {
private Node[] nodes;
public Graph(int vars) {
this.nodes = new Node[2 * vars];
for (var i = 0; i < nodes.length; i += 1) {
this.nodes[i] = new Node();
}
}
public int vars() {
return this.nodes.length / 2;
}
public Node get(int vari) {
return this.nodes[this.realIndex(vari)];
}
public void imply(int varA, int varB) {
this.nodes[this.realIndex(varA)].edges.add(varB);
this.nodes[this.realIndex(-varB)].edges.add(-varA);
}
private int realIndex(int vari) {
return vari > 0 ? (vari - 1) : (nodes.length + vari);
}
}
private static ArrayList<Integer> solve(Graph graph) {
for (var vari : findOrder(graph)) {
if (graph.get(vari).assignment == null) {
graph.get(vari).assignment = false;
graph.get(-vari).assignment = true;
}
}
var res = new ArrayList<Integer>();
for (var i = 1; i <= graph.vars(); i += 1) {
if (graph.get(i).assignment == true) {
res.add(i);
}
}
return res;
}
private static ArrayList<Integer> findOrder(Graph graph) {
var order = new ArrayList<Integer>();
for (var i = 1; i <= graph.vars(); i += 1) {
for (var v : new int[] { i, -i }) {
if (graph.get(v).time == -1) {
tarjan(graph, v, new Stack<Integer>(), order);
}
}
}
Collections.reverse(order);
return order;
}
private static int globalTime = 0;
private static void tarjan(Graph graph, int node, Stack<Integer> st, ArrayList<Integer> order) {
graph.get(node).time = graph.get(node).low = (globalTime += 1);
st.push(node);
graph.get(node).inStack = true;
for (var other : graph.get(node).edges) {
if (graph.get(other).time == -1) {
tarjan(graph, other, st, order);
graph.get(node).low = Math.min(graph.get(node).low, graph.get(other).low);
}
if (graph.get(other).inStack) {
graph.get(node).low = Math.min(graph.get(node).low, graph.get(other).time);
}
}
// Extract the strongly-connected component.
if (graph.get(node).low >= graph.get(node).time) {
while (order.isEmpty() || order.get(order.size() - 1) != node) {
var top = st.pop();
graph.get(top).inStack = false;
order.add(top);
}
}
}
private static class InOut implements AutoCloseable {
public MyScanner in;
public PrintStream out;
/** Constructor for using standard IO. */
public InOut() {
in = new MyScanner(new InputStreamReader(System.in));
out = System.out;
}
/** Constructor for using file IO. */
public InOut(String pathIn, String pathOut) throws IOException {
in = new MyScanner(new FileReader(pathIn));
out = new PrintStream(pathOut);
}
@Override
public void close() {
}
}
private static class MyScanner {
private BufferedReader br;
private StringTokenizer st;
public MyScanner(Reader reader) {
br = new BufferedReader(reader);
}
public String next() {
while (st == null || !st.hasMoreElements()) {
try {
st = new StringTokenizer(br.readLine());
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
return "";
}
}
return st.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
public long nextLong() {
return Long.parseLong(next());
}
public double nextDouble() {
return Double.parseDouble(next());
}
public String nextLine() {
String str = "";
try {
str = br.readLine();
} catch (IOException e) {
e.printStackTrace();
}
return str;
}
}
}