Disjoint-set "red alert"

topic:

War to maintain connectivity between various cities is very important. This question requires you to write a program alarm, when the city lost a lead country is split into multiple zones can not communicate, it emits red alert. Note: If the country should not have full connectivity, k is divided regions, a lost city does not alter the connectivity between other cities, do not alarm.

Input formats:

Input two integers are given in the first row N(0  N ≤ 500) and M( ≤ 5000), respectively, the number of city (city then default from 0 to N-1 numbered) and connections of the two cities via strip. Subsequently Mrows each given two cities connected via a number, separated by a space therebetween. It gives information was captured after city information, that is a positive integer Kand subsequently Ka number of cities were captured.

Note: Enter the city was captured guarantee given number is legitimate and no repeat, but does not guarantee passage given no repeat.

Output formats:

Each city was captured, if it will change the connectivity of the entire country, the output Red Alert: City k is lost!, which kis the city's number; otherwise, only the output City k is lost.can be. If the country lost its last city, then add a line output Game Over..

Sample input:

5 4
0 1
1 3
3 0
0 4
5
1 2 0 4 3
 

Sample output:

City 1 is lost.
City 2 is lost.
Red Alert: City 0 is lost!
City 4 is lost.
City 3 is lost.
Game Over.


①在判断是否改变连通性的时候,我第一个想法是每一个地点都找到pre,然后每次将两个地点加入并查集的时候都会不断更新pre使联通的地点的pre(即 爸爸 )都是相同的,最后我把新的pre数组和旧的pre数组进行比较看是否除了lost的城市之外有改变。
  我当时pre数组的记录方式是,每个pre记录共同的“爸爸”,而“爸爸”的pre是自己本身。
  这样出现的问题是,即使没有改变连通性每次lost一个城市重新用并查集得到的“爸爸”不一定相同。

②后来看了同学的代码,发现可以用 判断联通集合的个数 即爸爸的个数来判断是否联通。于是 我根据前后两次的“爸爸”数量是否相通来判断是否联通
  但是,我设置的pre[爸爸]为爸爸本身,如果是一个本来就孤立的城市,那么查询的时候就会把它当成一个爸爸。但实际这个城市的存在与否不会影响到连通性。

③再后来我再看了同学代码,将pre[爸爸]改为-1,在数爸爸个数的时候就数-1的个数(此时-1的个数不再是连通块的个数了,但是可以根据-1个数的变化来判断是否改变了连通性),这样可以彻底不考虑那些孤立的城市。
  但是如果是不孤立的尾端的城市lost了,结果就会多出一个-1,但是实际上也没有改变连通性。

④然后我就用一个变量death记录当前的lost城市,然后再数-1个数的时候跳过death。
  但是也是因此-1的数量没有更新,而在下一次找爸爸数量的时候又将这个-1算了进来,因此错误。

⑤最后我又又看了同学代码。因为如果是尾端的城市lost,那么-1个数就会比原来多一个;如果是影响连通性的城市lost,因为改变连通性多一个“爸爸”, 所以多了一个-1, 而lost的城市的pre也变成-1,那么最后多出来的-1就有两个。
  所以最后判断是否改变联通性的方式是 -1的个数是否与原来相等或者比原来多一个,如果是那么没有改变连通性,反之改变。

代码:
 1 #include <iostream>
 2 #include <fstream>
 3 #include <cstring>
 4 #include <algorithm>
 5 
 6 using namespace std;
 7 int N, M, areanum=-1;
 8 const int mx=510;
 9 int connection[mx][mx];
10 int root[mx],pre[mx];
11 
12 int findroot(int vs);
13 int findset();
14 void makefamily(int v1, int v2);
15 int main(){
16 fill(connection[0], connection[0]+mx*mx, -1);
17 fill(pre, pre+mx, -1);
18 
19 cin>>N>>M;
20 for(int i=1;i<=M;i++){
21     int a, b;
22     cin>>a>>b;
23     connection[a][b]=1;
24     connection[b][a]=1;
25     makefamily(a, b);
26 }
27 findset();
28 int K;
29 cin>>K;
30 int num=N;
31 for(int i=1;i<=K;i++){
32     int death;
33     cin>>death;
34     for(int city=0;city<N;city++){
35         if(connection[city][death]==1||connection[death][city]==1){
36             connection[city][death]=-1;
37             connection[death][city]=-1;
38         }
39     }
40     fill(pre, pre+mx, -1);
41 
42     for(int i=0;i<N;i++){
43         for(int j=0;j<N;j++){
44             if(connection[i][j]==1)
45                 makefamily(i,j);
46         }
47     }
48     int flag=findset();
49 
50     (flag==-1)?printf("Red Alert: "):0;
51     printf("City %d is lost", death);
52     (flag==-1)?puts("!"):puts(".");
53     num--;
54 }
55 if(num==0) cout<<"Game Over."<<endl;
56 }
57 int findset(){
58     int t=0, Fake = areanum;
 59      for ( int I = 0 ; I <N; I ++ ) {
 60         IF (pre [I] == - . 1 ) T ++ ;
 61 is      }
 62 is      areanum = T;
 63 is      return (T == Fake || Fake == + T . 1 )? . 1 : - . 1 ; // determines whether Unicom
 64  
65  }
 66  
67  void makefamily ( int V1, int V2) {
 68      int T = V2;
 69      V1 = the findroot (V1);
 70     v2=findroot(v2);
71     if(v1!=v2){
72         pre[v2]=v1;
73     }
74 }
75 int findroot(int vs){
76     while(pre[vs]!=-1)     vs=pre[vs];
77     return vs;
78 }

 

Later Baidu a bit and found dfs can also be used to do this question hhh.

As https://blog.csdn.net/sgh666666/article/details/79752816

 



Guess you like

Origin www.cnblogs.com/sloth612/p/12536725.html