Pagini recente » Cod sursa (job #1224828) | Cod sursa (job #1951284) | Cod sursa (job #88974) | Cod sursa (job #2736331) | Cod sursa (job #1749131)
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
InputReader in = new InputReader(new FileInputStream("ctc.in"));
int N = in.nextInt();
int M = in.nextInt();
Graph G = new Graph(N);
for (int i = 0; i < M; i++) {
int u = in.nextInt();
int v = in.nextInt();
G.addEdge(u, v);
}
in.close();
TarjanStronglyConnected TSC = new TarjanStronglyConnected(G);
int[] components = TSC.computeStronglyConnectedComponents();
int n = TSC.getNumberOfStronglyConnectedComponents();
ArrayList<ArrayList<Integer>> lists = new ArrayList<ArrayList<Integer>>();
for (int i = 0; i < n; i++) {
lists.add(new ArrayList<Integer>());
}
for (int i = 1; i <= N; i++) {
lists.get(components[i] - 1).add(i);
}
PrintWriter out = new PrintWriter(new FileOutputStream("ctc.out"));
out.println(lists.size());
for (int i = 0; i < lists.size(); i++) {
for (int x : lists.get(i)) {
out.printf("%d ", x);
}
out.printf("\n");
}
out.flush();
out.close();
}
static class TarjanStronglyConnected {
private final Graph G;
private final int N;
private final int[] index, lowlink;
private final boolean[] onStack;
private final Stack<Integer> stack;
private int numberOfSCCs;
private int[] component;
private int _index;
TarjanStronglyConnected(Graph graph){
this.G = graph;
this.N = graph.getN();
index = new int[N + 1];
lowlink = new int[N + 1];
onStack = new boolean[N + 1];
stack = new Stack<>();
}
private void dfs(int node){
index[node] = _index;
lowlink[node] = _index;
_index++;
onStack[node] = true;
stack.push(node);
for (int p = G.getHead(node); p != Graph.NIL; p = G.getNext(p)) {
int son = G.getNeighbour(p);
if (index[son] == -1){
dfs(son);
lowlink[node] = Math.min(lowlink[node], lowlink[son]);
}
else if (onStack[son])
lowlink[node] = Math.min(lowlink[node], index[son]);
}
if (index[node] == lowlink[node]){
numberOfSCCs++;
int w;
do {
w = stack.peek();
onStack[w] = false;
stack.pop();
component[w] = numberOfSCCs;
} while (w != node);
}
}
int[] computeStronglyConnectedComponents(){
component = new int[N + 1];
_index = 0;
numberOfSCCs = 0;
Arrays.fill(component, -1);
Arrays.fill(index, -1);
Arrays.fill(onStack, false);
stack.clear();
for (int i = 1; i <= N; i++) {
if (index[i] == -1)
dfs(i);
}
return component;
}
int getNumberOfStronglyConnectedComponents(){
return numberOfSCCs;
}
}
static class Graph{
private static class Edge{
int node;
int next;
Edge(int node, int next){
this.node = node;
this.next = next;
}
}
final static int NIL = -1;
private int[] head;
private int[] degree;
private ArrayList<Edge> graph;
private int N;
private int counter;
Graph(int N){
initialize(N);
}
public int getN() {
return N;
}
private void initialize(final int N){
head = new int[N];
degree = new int[N];
graph = new ArrayList<>();
this.N = N;
this.counter = 0;
Arrays.fill(head, NIL);
Arrays.fill(degree, 0);
}
void addEdge(int x, int y){
if (!(1 <= x && x <= N)) throw new AssertionError();
x--; y--;
graph.add(new Edge(y, head[x]));
head[x] = counter++;
degree[x]++;
}
int getHead(int node){
if (!(1 <= node && node <= N)) throw new AssertionError();
node--;
return head[node];
}
int getNext(int p){
if (!(0 <= p && p < counter)) throw new AssertionError();
return graph.get(p).next;
}
int getNeighbour(int p){
if (!(0 <= p && p < counter)) throw new AssertionError();
return graph.get(p).node + 1;
}
boolean isEmpty(int node){
if (!(1 <= node && node <= N)) throw new AssertionError();
node--;
return head[node] == NIL;
}
int size(int node){
assert 1 <= node && node <= N;
node--;
return degree[node];
}
Graph transpose(){
Graph GT = new Graph(N);
for (int i = 1; i <= N; i++) {
for (int son : getNeighbours(i))
GT.addEdge(son, i);
}
return GT;
}
List<Integer> getNeighbours(int node){
if (!(1 <= node && node <= N)) throw new AssertionError();
List<Integer> list = new ArrayList<>();
for (int p = head[node - 1]; p != NIL; p = graph.get(p).next) {
list.add(graph.get(p).node + 1);
}
return list;
}
}
static class InputReader{
private BufferedReader reader;
private StringTokenizer tokenizer;
private InputStream inputStream;
InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 1 << 20);
tokenizer = null;
inputStream = stream;
}
private String nextToken() {
while (tokenizer == null || !tokenizer.hasMoreTokens()){
try {
tokenizer = new StringTokenizer(reader.readLine());
}
catch (IOException e){
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
int nextInt() {
return Integer.parseInt(nextToken());
}
String nextString(){
return nextToken();
}
void close() throws IOException {
inputStream.close();
}
}
}