Tarjan 无向图计算最大环(最小环) java实现 Poj3895

Tarjan计算最大环(或者最小环)

题目链接:Cycles of Lanes

最大环模板题

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.ArrayDeque;
import java.util.LinkedList;
import java.util.StringTokenizer;

public class Main {
static int[] dfn,low;
static boolean[] visit;
static LinkedList[] adj;
static int visitCnt,result;
static ArrayDeque stack;

public static void main(String[] args) throws Exception{
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    StringTokenizer st = new StringTokenizer(br.readLine());
    int T = Integer.parseInt(st.nextToken());
    for(int testcase = 1;testcase<=T;testcase++){
        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];
        visit = new boolean[n+1];
        adj = new LinkedList[n+1];
        stack = new ArrayDeque<Integer>();
        for(int i = 0;i<adj.length;i++){
            adj[i] = new LinkedList<Integer>();
        }
        result = 0;

        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(to);
            adj[to].add(from);
        }

        for(int i = 1;i<=n;i++){
            if(!visit[i]){
                tarjan(i,-1);
            }
        }
        System.out.println(result);
    }
}

private static void tarjan(int from,int fromParent){
    dfn[from] = low[from] = ++visitCnt;
    visit[from] = true;
    stack.push(from);
    for(int to:adj[from]){
        if(to == fromParent){
            continue;
        }
        if(dfn[to] == 0){
            int temp = visitCnt;
            tarjan(to,from);
            visitCnt = temp;
            low[from] = Math.min(low[from],low[to]);
        }
        else if(visit[to]){
            low[from] = Math.min(low[from],dfn[to]);
            result = Math.max(result,dfn[from]-dfn[to]+1);
        }
    }

    if(dfn[from] == low[from]){
        int popPoint;
        do{
            popPoint = stack.pop();
            visit[popPoint] = false;
        }while (dfn[popPoint]!=low[popPoint]);
    }
}

}

posted @ 2021-04-30 17:27  Monstro  阅读(312)  评论(0)    收藏  举报