Hiho: 连通图

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

还记得上次小Hi和小Ho学校被黑客攻击的事情么,那一次攻击最后造成了学校网络数据的丢失。为了避免再次出现这样的情况,学校决定对校园网络进行重新设计。

学校现在一共拥有N台服务器(编号1..N)以及M条连接,保证了任意两台服务器之间都能够通过连接直接或者间接的数据通讯。

当发生黑客攻击时,学校会立刻切断网络中的一条连接或是立刻关闭一台服务器,使得整个网络被隔离成两个独立的部分。

举个例子,对于以下的网络:

每两个点之间至少有一条路径连通,当切断边(3,4)的时候,可以发现,整个网络被隔离为{1,2,3},{4,5,6}两个部分:

若关闭服务器3,则整个网络被隔离为{1,2},{4,5,6}两个部分:

小Hi和小Ho想要知道,在学校的网络中有哪些连接和哪些点被关闭后,能够使得整个网络被隔离为两个部分。

在上面的例子中,满足条件的有边(3,4),点3和点4。

提示:割边&割点

输入

第1行:2个正整数,N,M。表示点的数量N,边的数量M。1≤N≤20,000, 1≤M≤100,000

第2..M+1行:2个正整数,u,v。表示存在一条边(u,v),连接了u,v两台服务器。1≤u<v≤N

保证输入所有点之间至少有一条连通路径。

输出

第1行:若干整数,用空格隔开,表示满足要求的服务器编号。从小到大排列。若没有满足要求的点,该行输出Null

第2..k行:每行2个整数,(u,v)表示满足要求的边,u<v。所有边根据u的大小排序,u小的排在前,当u相同时,v小的排在前面。若没有满足要求的边,则不输出

样例输入
6 7
1 2
1 3
2 3
3 4
4 5
4 6
5 6
样例输出
3 4
3 4


  1 import java.util.ArrayList;
  2 import java.util.HashSet;
  3 import java.util.Scanner;
  4 import java.util.Set;
  5 import java.util.Stack; 
  6 import java.util.TreeSet;
  7 
  8 
  9 
 10 public class Main {
 11     
 12     static int N_Max=0;  //记录根节点是否有两个或多个子树
 13     static int NUM=0;    //记录已经遍历的个数
 14     static int [] checktable;
 15     static int [] havechecktable;    
 16     static Stack<Integer> stack=new Stack();    
 17     public static void main(String[] argv){        
 18         Scanner in = new Scanner(System.in);
 19         int N = in.nextInt();
 20         int M = in.nextInt();
 21         checktable= new int[N];          //记录遍历顺序
 22         havechecktable= new int[N];   //记录是否已经遍历的标示
 23         int[] y_min= new int[N];      //记录非树边所能达到的小次序值
 24         int[] min = new int[N];       //记录Low值
 25         int[] sort_check = new int[N];//记录每个id点的遍历次序
 26         ArrayList<Integer> [] source = new ArrayList[N];        //记录图的矩阵
 27         ArrayList<Integer> [] blue = new ArrayList[N];       //记录遍历树的矩阵
 28         Set<String> out_xian = new HashSet<String>();
 29         Set<Integer> out_dian = new HashSet<Integer>();
 30         ArrayList<Integer> [] out_xian_2 = new ArrayList[N];
 31         int[][] xian_resource = new int[N][N];
 32         //ArrayList<Integer> out_dian = new ArrayList<Integer>();
 33         //ArrayList out_xian = new ArrayList();
 34         //初始化矩阵
 35         for(int i=0; i<N; i++){
 36             source[i] = new ArrayList<Integer>();
 37             blue[i] = new ArrayList<Integer>();
 38             out_xian_2[i] = new ArrayList<Integer>();
 39         }
 40         /************************记录矩阵**********************/
 41         for(int i=0; i<M; i++){    
 42             int x=in.nextInt()-1; int y= in.nextInt()-1;
 43             source[x].add(y);
 44             source[y].add(x);
 45         }        
 46         /************************深度遍历**********************/
 47         dfn(source, checktable, blue);
 48         
 49         /************************验证非树边**********************/
 50         /*
 51         //System.out.println("BLUE:  ");                
 52         for(int i=0; i<N; i++){
 53             
 54             System.out.println("     "+blue[i].toString());
 55         }
 56         */
 57        /************************get sort_check[](即 dfn[])**********************/        
 58         for(int i=0; i<N; i++){                
 59             source[i].removeAll(blue[i]);        
 60             sort_check[checktable[i]]=i;            
 61         }
 62         /************************验证dfn[] and y_min[]**********************/    
 63         /*
 64         System.out.println("Sort_Check:  ");
 65         for(int i=0; i<N; i++){                            
 66             System.out.println("  "+sort_check[i]);
 67         }        
 68         System.out.println("YELLOW:  ");
 69         for(int i=0; i<N; i++){
 70             System.out.println(source[i].toString());            
 71         }
 72         */    
 73         /************************Get the y_low[]**********************/    
 74         //System.out.println("YELLOW_min:  ");
 75         for(int i=0; i<N; i++){
 76             int ymin=i;            
 77             for(Object k: source[checktable[i]]){            
 78                 int spit = sort_check[(int)k];
 79                 if(spit<ymin)
 80                     ymin=spit;
 81             }            
 82             //System.out.print(" "+ymin);
 83             y_min[i]=ymin;
 84         }        
 85         /************************Get the low[]**********************/    
 86         //System.out.println();
 87         //System.out.println("Low: ");
 88         for(int i=N-1; i>=0; i--){              
 89             int k_low = checktable[i];
 90             min[i]=y_min[i];
 91             for(Object o_int : blue[k_low] ){
 92                 
 93                 if(sort_check[k_low]<sort_check[(int)o_int]){
 94                     
 95                     if(min[i]>min[sort_check[(int)o_int]])
 96                         min[i]=min[sort_check[(int)o_int]];                    
 97                 }                
 98             }
 99            // Low[]
100         //System.out.println("  "+i+"  "+k_low+":  "+min[i]);
101         }        
102         /************************Get result**********************/                    
103         for(int i=0; i<N; i++){
104             
105             for(Object blue_k : blue[i]){
106                 
107                 //System.out.println(i+":  "+min[sort_check[(int)blue_k]]+">="+sort_check[i]);
108                 if(min[sort_check[(int)blue_k]]>=sort_check[i]){
109                     //System.out.println(i+" added. ");
110                 if(i>0)
111                     out_dian.add(i+1);
112                 if(min[sort_check[(int)blue_k]]>sort_check[i]){
113                     //String temp = "";
114                     int x=i+1; 
115                     int y=(int)blue_k+1;
116                     if(i<(int)blue_k){
117                         //temp=x+" "+y;
118                         out_xian_2[i].add((int)blue_k);
119                     }
120                     else{
121                         //temp=y+" "+x;
122                         out_xian_2[(int)blue_k].add(i);
123                     }                    
124 
125                     
126                 }
127                 }                
128             }                
129         }
130         if(N_Max>1)
131             out_dian.add(1);
132         //System.out.println(out_dian.toString());
133         /************************Output result**********************/    
134         java.util.Iterator<Integer> it_dian=out_dian.iterator();
135         //java.util.Iterator<String> it_xian=out_xian.iterator();
136         int[] dian_sqit_list = new int[N+1];
137         String dian_result="";
138         while(it_dian.hasNext())
139           {
140             dian_sqit_list[it_dian.next()]=1;
141             //dian_result=dian_result+it_dian.next()+" ";
142          }
143         for(int i=1; i<=N; i++){
144             if(dian_sqit_list[i]==1)
145                 dian_result=dian_result+i+" ";
146         }    
147         //System.out.println("::::::"+dian_result);
148         if(dian_result.length()>1){
149             dian_result=dian_result.substring(0,dian_result.length()-1);
150             System.out.println(dian_result);    
151         }
152         else
153             System.out.println("Null");    
154                     
155         for(int i=0; i<N; i++){
156 
157             int[] out_xian_temp = new int[N];
158             for(int out_m : out_xian_2[i]){
159                 
160                 out_xian_temp[out_m]=1;
161             
162             }
163             for(int j=0; j<N;j++ ){
164                 
165                 if(out_xian_temp[j]==1){
166                 System.out.print(i+1);    
167                 System.out.print(" ");
168                 System.out.println(j+1);
169                 }
170                 
171             
172             }
173                     
174         }
175         
176         /*
177         while(it_xian.hasNext())
178           {
179           System.out.println(it_xian.next());
180          }    
181          */
182     }
183     
184     public static void dfn(ArrayList[] source, int[] checktable, ArrayList[] blue){
185         
186         //int size = source.length;
187         int start =0;
188         checktable[NUM++]=start;
189         havechecktable[start]=1;
190         stack.push(start);
191         while(true){
192             
193             int end = Had(source[start],start,checktable,havechecktable);
194             if(end>=0){
195                 if(start==0)
196                     N_Max++;
197                 blue[start].add(end);
198                 blue[end].add(start);                
199                 //System.out.println(end);
200                 stack.push(end);
201                 //stack.push(start);
202                 //start = end;        
203                 //System.out.println("start:"+start+"   end"+end+"  "+"NUM:"+NUM);
204                 checktable[NUM++]=end;
205                 havechecktable[end]=1;
206             }
207             else{
208             
209                 stack.pop();
210             }
211             if(stack.isEmpty())
212                 break;    
213             else{
214                  start=stack.pop();
215                  stack.push(start);
216             }
217            
218             
219         }
220         //System.out.println(N_Max);
221 
222     }
223     
224     public static int Had(ArrayList s_source, int s_check, int[] check_table, int[] havechecked){
225         
226         for(int i=0; i<s_source.size();i++){
227             //System.out.println(s_source.toString());
228             int key = (int)s_source.get(i);
229             //System.out.println(key);
230             if(havechecked[key]==0){                
231                 return key;            
232             }            
233         }
234         
235         return -1;
236     }
237 }
原文地址:https://www.cnblogs.com/udld/p/4620304.html