import java.util.*;
import java.lang.*;
import java.io.*;
public class Main{
static int n, e; //vertices, arcos
static int MAX=1010;
static ArrayList
<Integer
> ady
[]=new ArrayList [MAX
]; static boolean marked[]=new boolean [MAX];
static int prev[]=new int [MAX];
static int dfs_low[]=new int [MAX];
static int dfs_num[]=new int [MAX];
static int itsmos[]=new int [MAX];
static ArrayList<Edge> bridges;
static int dfsRoot, rootChildren, cont;
int i;
n = 6;
init();
ady[0].add(1); ady[1].add(0);
ady[1].add(2); ady[2].add(1);
ady[4].add(1); ady[1].add(4);
ady[3].add(4); ady[4].add(3);
ady[4].add(5); ady[5].add(4);
puntosArticulacionYPuentes();
/*****************************/
n = 6;
init();
ady[0].add(1); ady[1].add(0);
ady[1].add(2); ady[2].add(1);
ady[4].add(1); ady[1].add(4);
ady[3].add(1); ady[1].add(3);
ady[4].add(5); ady[5].add(4);
ady[1].add(5); ady[5].add(1);
puntosArticulacionYPuentes();
/*****************************/
n = 3;
init();
ady[0].add(1); ady[1].add(0);
ady[1].add(2); ady[2].add(1);
ady[2].add(0); ady[0].add(2);
puntosArticulacionYPuentes();
}
static void puntosArticulacionYPuentes(){
int i;
cont = 0;
dfsRoot = 0;
rootChildren = 0;
dfs(0);
System.
out.
println("PUNTOS DE ARTICULACIÓN"); for(i = 0; i < n; i++ ){
if( itsmos[i] == 1 ){
if( i == dfsRoot ){
if( rootChildren
> 1 ) System.
out.
println(i
); }
}
System.
out.
println("PUENTES"); for(i = 0; i < bridges.size(); i++ ){
System.
out.
println(bridges.
get(i
).
src + " " + bridges.
get(i
).
dest ); }
}
static void init() {
bridges=new ArrayList<Edge>();
cont=0;
int i;
for(i=0; i<n; i++){
ady[i]=new ArrayList<Integer>();
marked[i]=false;
prev[i]=-1;
itsmos[i]=0;
}
}
static void dfs(int u){
dfs_low[u]=cont;
dfs_num[u]=cont;
cont++;
marked[u]=true;
int j, v;
for(j=0; j<ady[u].size(); j++){
v=ady[u].get(j);
if(!marked[v]){
prev[v]=u;
//Caso especial
if(u==dfsRoot){
rootChildren++;
}
dfs(v);
//PARA ITSMOS
if(dfs_low[v]>=dfs_num[u]){
itsmos[u]=1;
}
//PARA PUENTES
if(dfs_low[v]>dfs_num[u]){
bridges.
add(new Edge
(Math.
min(u,v
),
Math.
max(u,v
))); }
dfs_low
[u
]=Math.
min(dfs_low
[u
], dfs_low
[v
]); }else if(v!=prev[u]){ //Arco que no sea backtrack
dfs_low
[u
]=Math.
min(dfs_low
[u
], dfs_num
[v
]); }
}
}
static class Edge{
public int src, dest;
public Edge(int s, int d) {
this.src = s;
this.dest = d;
}
}
}