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 }

时间: 2024-12-11 16:44:23

Hiho: 连通图的相关文章

Hiho 1014 题目

hiho一下第二周 Hihocoder #1014 : Trie树 ? 参考链接:http://m.blog.csdn.net/blog/u012662688/38354777 ? Java实现: ? import java.io.BufferedInputStream; import java.util.Scanner; ? ? public class Main { ????public static void main(String[] args) {???????? ????????Sc

欧拉路径 提高篇 hiho第51周

题目链接:hiho 第51周 思路:首先特判n=1的情况,无输出.对于其他的按有向欧拉路径的求法把欧拉路径求出来以后,第一个按位全输出,接下来的的(2^n-1)个点,只需要输出二进制最后一位就可以了.详细的思路参考hiho 第51周 /************************************************************** Problem:hiho 第51周 User: youmi Language: C++ Result: Accepted Time:17m

[hiho 01]最长回文子串、Manacher算法

题目描述 - 基础方法:枚举子串,判断是否为回文串. - 改进:枚举中间位置,向两侧拓展. - 再改进:利用以前的信息,使得不用每个新位置都从长度1开始拓展. - 优化:将字符串预处理为奇数长度以避免考虑条件分支. - 再优化:开头加入特殊字符避免考虑边界. Manacher 算法: id 是中心点,mx 是其边界.P[i] 表示以 i 为中心的最长回文子串的折半长度. 只要 i < mx, 以 i 为中心的回文子串就可以不必从长度1开始找,而从min{P[j], mx - i}开始(其中j为i

题目1545:奇怪的连通图

奇怪的连通图 题目描述: 已知一个无向带权图,求最小整数k.使仅使用权值小于等于k的边,节点1可以与节点n连通. 输入: 输入包含多组测试用例,每组测试用例的开头为一个整数n(1 <= n <= 10000),m(1 <= m <= 100000),代表该带权图的顶点个数,和边的个数.接下去m行,描述图上边的信息,包括三个整数,a(1 <= a <= n),b(1 <= b <= n),c(1 <= c <= 1000000),表示连接顶点a和顶

hiho一下 第二十一周(线段树 离散化)

知识点1:离散化  对于这些区间来说,其实并不会在乎具体数值是多少,而是在他们的左右端点之间互相进行比较而已.所以你就把这N个区间的左右端点——2N个整数提出来,处理一下呗?你要注意的是,这2N个数是什么其实并不重要,你可以把这2N个数替换成为任何另外2N个数,只要他们之间的相对大小关系不发生改变就可以.” 解决方法: 那么我需要额外做的事情就是在构建线段树之前对区间进行预处理:将区间的左右端点选出来,组成一个集合,然后将这个集合依次对应到正整数集合上,并且利用这个对应将原来的区间的左右端点更换

hiho一下 第115周:网络流一?Ford-Fulkerson算法 (Edmond-Karp,Dinic,SAP)

来看一道最大流模板水题,借这道题来学习一下最大流的几个算法. 分别用Edmond-Karp,Dinic ,SAP来实现最大流算法. 从运行结过来看明显SAP+当前弧优化+gap优化速度最快.   hiho一下 第115周:网络流一•Ford-Fulkerson算法 原题网址:http://hihocoder.com/contest/hiho115/problem/1 网络流一·Ford-Fulkerson算法 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi和

Fleury算法求欧拉路径 hiho第50周

题目链接: hiho一下 第五十周 思路:hiho已经讲的非常好了,我就不插嘴了. 提示:因为建边时同一条边同相反相的编号相近,比如(u-v)正向边u->v标号为0,反向边v->u标号为1,而0或1除以2都等于0,所以无论正反向建边,只要访问过正向反向中的任何一条边都可以用head[u]/2把原边标记为vis=1操作 /************************************************************** Problem:hiho 50 User: you

欧拉路径 基础题 hiho第49周

题目链接:hiho 第49周 思路: 定义:给定无孤立结点图G,若存在一条路,经过图中每边一次且仅一次,该条路称为欧拉路. 性质:  1: 一个无向图存在欧拉路当且仅当该图是连通的且有且只有2个点的度数是奇数,此时这两个点只能作为欧拉路径的起点和终点.  2: 若图中没有奇数度的点,那么起点和终点一定是同一个点,这样的欧拉路叫做欧拉回路 利用性质做题就好了,具体的模拟hiho讲的非常清楚了 /****************************************************

【连通图|强连通分量+缩点】POJ-1236 Network of Schools

Network of Schools Time Limit: 1000MS Memory Limit: 10000K Description A number of schools are connected to a computer network. Agreements have been developed among those schools: each school maintains a list of schools to which it distributes softwa