hdu1269迷宫城堡-Tarjan强连通(java)

Tarjan的几个关键点:
1.DFS基本思路:先访问当前节点,标记为已访问,之后DFS相邻节点。
2.Stack储存节点,遍历过程中每个节点记录time(时间戳),low数组(标识每个强连通分量)
3.边界条件:当一个节点没有后驱节点此节点 (即他的dfn=他的low)时。
4.存图:list或者邻接矩阵

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Stack;

public class Main {
    private static ArrayList[] list ;
    private static int[] dfn ;
    private static int[] low ;
    private static int[] instack ;
    private static int[] vis ;
    private static int time,sum ;
    private static Stack<Integer> stack ;
    private static void Tarjan(int i){
        dfn[i] = low[i] = ++time ;
        stack.push(i) ;
        instack[i] = 1 ;
        for(int j=0;j<list[i].size();j++){
            int k = (int)list[i].get(j) ;
            if(vis[k]==0){
                vis[k]=1 ;
                Tarjan(k) ;
                low[i] = Math.min(low[i],low[k]) ;
            }else if(instack[k]==1){
                low[i] = Math.min(low[i],dfn[k]) ;
            }
        }
        if(low[i]==dfn[i]){
            sum++ ;
            int k ;
            do{
                k = stack.pop() ;
                instack[k] =  0 ;
            }while(i!=k&&!stack.isEmpty()) ;
        }
    }
    public static void main(String[] args) throws IOException {
        StreamTokenizer in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in))) ;
        while(in.nextToken()!=StreamTokenizer.TT_EOF){
            int N = (int)in.nval ;
            in.nextToken() ;
            int M = (int)in.nval ;
            if(N==0&&M==0)break ;
            list = new ArrayList[N+1] ;
            for (int i = 0; i <= N; i++) {
                list[i] = new ArrayList<Integer>() ;
            }
            for (int i = 0; i < M; i++) {
                in.nextToken() ;
                int x = (int)in.nval ;
                in.nextToken() ;
                int y = (int)in.nval ;
                list[x].add(y) ;
            }
            dfn = new int[N+1] ;
            low = new int[N+1] ;
            time = 0 ;
            sum = 0 ;
            stack = new Stack<>();
            instack = new int[N+1] ;
            vis = new int[N+1] ;
            int h = 0 ;
            for(int i=1;i<=N;i++){
                if(vis[i]==0){
                    vis[i] = 1 ;
                    h++ ;
                    if(h>=2){
                        sum = 2 ;
                        break ;
                    }
                    Tarjan(i) ;
                }
            }
            if(sum==1){
                System.out.println("Yes") ;
            }else{
                System.out.println("No") ;
            }
        }
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值