Bi Connected Components

From programming_contest
Jump to navigation Jump to search
/**
 * BiConnected Components/Doubly Connected Components
 * @param in the adjacency list
 * @return list of edges by biconnected component
 */
public ArrayList<ArrayList<Point>> biConnectedComponents(ArrayList<ArrayList<Integer>> in){
	int[][] t=new int[3][in.size()];//order,link,various indices
	Stack<Point> s=new Stack<Point>();
	ArrayList<ArrayList<Point>> out=new ArrayList<ArrayList<Point>>();
	HashSet<Point>u=new HashSet<Point>();
	for(int i=0;i<in.size();i++)if(t[0][i]==0)dfs(i,in,out,s,t,u);//this only necessary for unconnected components....
	if(!s.isEmpty())out.add(new ArrayList<Point>(s));
	return out;
}
private void dfs(int i,ArrayList<ArrayList<Integer>> in,ArrayList<ArrayList<Point>> out,Stack<Point> s ,int[][] t, HashSet<Point> u) {
	t[1][i]=t[0][i]=++t[2][0];
	int min=t[1][i];//need this because we can't update the min until after we've finished all recursion
	for(int j:in.get(i)){
		if(u.contains(new Point(j,i)))continue;//if already traversed this edge in the other direction
		u.add(new Point(i,j));
		s.push(new Point(i,j));
		if(t[0][j]==0)dfs(j,in,out,s,t,u);//don't  recurse on previously visited nodes
		min=Math.min(min,t[1][j]);
		if(t[0][i]<=t[1][j]){
			ArrayList<Point> al=new ArrayList<Point>();
			while(al.size()==0||al.get(al.size()-1).x!=i)al.add(s.pop());//pop through the edge that had i as the outgoing node
			out.add(al);
		}
	}
	t[1][i]=min;
}