Tarjan 模板 缩点 受欢迎的牛 Java实现
我讨厌🐂......
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.StringTokenizer;
public class Main implements Runnable{
static int[] dfn,low,parent;
static int[] stack,colorTypeCnt,pointColor,outDegrees;
static int colorTypeName,visitCnt,stackIdx;
static boolean[] mark,isInStack;
static LinkedList
static class Edge{
int from,to;
public Edge(int from, int to) {
this.from = from;
this.to = to;
}
}
public static void main(String[] args) {
new Thread(null,new Main(),"",1<<29).start();
}
@Override
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int m = Integer.parseInt(st.nextToken());
dfn = new int[n+1];
low = new int[n+1];
parent = new int[n+1];
stack = new int[n+1];
colorTypeCnt = new int[n+1];
pointColor = new int[n+1];
outDegrees = new int[n+1];
mark = new boolean[n+1];
isInStack = new boolean[n+1];
adj = new LinkedList[n+1];
for(int i = 0;i<adj.length;i++){
adj[i] = new LinkedList<>();
}
int from,to;
for(int i = 0;i<m;i++){
st = new StringTokenizer(br.readLine());
from = Integer.parseInt(st.nextToken());
to = Integer.parseInt(st.nextToken());
adj[from].add(new Edge(from,to));
}
for(int i = 1;i<=n;i++){
if(!mark[i]){
dfs(i);
}
}
for(int i = 1;i<=n;i++){
for(Edge e:adj[i]){
if(pointColor[i]!=pointColor[e.to]){
outDegrees[pointColor[i]]++;
}
}
}
int resultColorName=0;
for(int i = 1;i<=colorTypeName;i++){
if(outDegrees[i] == 0){
if(resultColorName!=0){
System.out.println(0);
return;
}
resultColorName = i;
}
}
System.out.println(colorTypeCnt[resultColorName]);
}catch (Exception e){
e.printStackTrace();
}
}
private static void dfs(int start){
dfn[start] = low[start] = visitCnt;
parent[start] = -1;
stack[++stackIdx] = start;
isInStack[start] = true;
mark[start] = true;
for(Edge e:adj[start]){
int to = e.to;
if(!mark[to]){
mark[to] = true;
parent[to] = start;
dfs0(to);
}
}
if(dfn[start] == low[start]){
colorTypeName++;
do{
pointColor[stack[stackIdx]] = colorTypeName;
colorTypeCnt[colorTypeName]++;
isInStack[stack[stackIdx]] = false;
stackIdx--;
}while (start!=stack[stackIdx+1]);
}
}
private static void dfs0(int from){
dfn[from] = low[from] = ++visitCnt;
stack[++stackIdx] = from;
isInStack[from] = true;
for(Edge e:adj[from]){
int to = e.to;
if(!mark[to]){
mark[to] = true;
parent[to] = from;
dfs0(to);
low[from] = Math.min(low[from],low[to]);
}
else{
low[from] = Math.min(low[from],dfn[to]);
}
}
if(dfn[from]==low[from]){
colorTypeName++;
do{
pointColor[stack[stackIdx]] = colorTypeName;
colorTypeCnt[colorTypeName] ++;
isInStack[stack[stackIdx]] = false;
stackIdx--;
}while (from !=stack[stackIdx+1]);
}
}
}

浙公网安备 33010602011771号