P1197 [JSOI2008] Star Wars [FIG disjoint-set theory +]

Topic Source: Luo Gu

Title Description

A long time ago, in a galaxy far far away, a dark empire against its super weapon ruled the galaxy.

One day, with a chance opportunity, a rebel destroyed the Imperial weapon, and the capture of nearly all galaxies planet. These planets directly or indirectly connected to each other by a special Ethernet tunnel.

But it did not last long, and soon the Empire again create his super weapon. With the power of this super weapon, the Empire began a systematic destruction of the planet Rebel occupation. As the planet continues to be destroyed, the communication channel between the two planets began unreliable up.

Now, the rebel leader give you a task: to give Ethernet connectivity tunnel and the planet against the order of the empire between the original two planets to try to quickly find every blow after rebels occupied the planet of communication block number. (If two planets may communicate directly or indirectly through the existing Ethernet channel, the two planets in the same communication block).

Input and output formats

Input formats:

 

The first line of the input file contains two integers, N  ( . 1 < = N < = 2 M) and  M  ( . 1 < = M < = 2 0 0 , 0 0 0), respectively, and the number of tunnels planet ether FIG. Planet with  0 ~  N. 1-  integer number.

The next  M rows, each row comprising two integers  X-,  the Y , where (  0 < = X- < > the Y represents planet  X X planet and  y have "ether" y tunnel, direct communication.

Next, a behavior of an integer  k, representing the number of the attack planet.

The next  k  lines, each line has an integer, in the order listed the targets Imperial Army. This  k  number of different from each other and are  0  to  n- - 1 range.

 

Output formats:

 

The first row is the number of blocks communicated at the beginning of the planet. The next  K  lines, each an integer representing the number of communication times hit the blocks after the existing planet.

 

Sample input and output

Input Sample # 1: 
8 13
0 1
1 6
6 5
5 0
0 6
1 2
2 3
3 4
4 5
7 1
7 2
7 6
3 6
5
1
6
3
5
7
Output Sample # 1: 
1
1
1
2
3
3

Explanation

[JSOI2008]

 

This question is the test code that force and thinking, need to disjoint-set and in-depth understanding of graph theory.

Resolution:

See this question, if we understand the meaning according to topic, you can easily get the idea, as long as a disjoint-set build, maintain Unicom block it.

But the meaning of the questions, we point from which to delete, and counts the number of China Unicom after each block delete finish point.

This is very very big head, we know, disjoint-set disjoint-set, easy to remove merger difficulty, how can this do na?

Yes, you might have thought, since the merger easier than delete, then we may wish to reverse thinking, converse solution.

We change the subject a bit, let's call it "Rebel reconstruction plan" Well qwq:

A long time ago, in a galaxy far far away, rebels to make up for the loss of the Imperial Army before the attack began rebuilding plan.

Now, the rebel leader give you a task: to give the planet to rebuild and reconstruction plan for all Ethernet tunnel between the stars and other planets, to try to quickly find the planet after each finished rebuilding a planet occupied by rebels communicating the number of blocks. (If two planets may communicate directly or indirectly through the existing Ethernet channel, the two planets in the same communication block).

Hey, this is not much simpler? And just with the original title, in turn, obtained the solution also happens in reverse order.

The idea is still the same, rebuilt after each planet, the planet and the planet Unicom plans to merge in and check focus, This question is complete.

 

But a point to mention here, on the adjacent table. In this problem, we certainly can put all the planets seen as an undirected graph, and stored using adjacency list.

But in fact we can interpret it this way: the adjacent table header can be used to indicate the relationship between China Unicom will be rebuilt one planet and other planets.

 

Reference Code:

1  // Resistance renewal program qwq 
2 #include <cstdio>
 . 3 #include <the iostream>
 . 4 #include <algorithm>
 . 5 #include <Queue>
 . 6 #include <Vector>
 . 7 #include <CString>
 . 8  #define N 100010
 . 9  the using  namespace STD;
 10  // adjacency table stored in FIG 
. 11  struct Node {
 12 is      int Next, Ver, from ;
 13 is } G [N << 2 ];
 14  int n-, m, K, TOT;
 15  int head [N << 2],ans[N<<2],fa[N<<2],b[N<<2];
16 bool v[N<<2];//是否需要重建 
17 void add(int x,int y)
18 {
19     g[++tot].ver=y,g[tot].from=x;
20     g[tot].next=head[x],head[x]=tot;
21 }
22 int get(int x)
23 {
24     if(fa[x]==x) return x;
25     return fa[x]=get(fa[x]);
26 }
27 void merge(int x,int y) 
28 {
29     x=get(x),y=get(y);
30     if(x!=y) fa[x]=y;
31 }
32 int main()
33 {
34     memset(v,0,sizeof(v));
35     memset(b,0,sizeof(b));
36     scanf("%d%d",&n,&m);
37     
38     for(int i=0;i<n;i++) fa[i]=i;//初始化 
39     
40     for(int i=1;i<=m;i++){
41         int x,y;
42         scanf("%d%d",&x,&y);
43         add(x,y),add(y,x);
44     }
45     scanf("%d",&k);
46     //需要重建的星球 
47     for(int i=1;i<=k;i++){
48          Scanf ( " % D " , & B [I]);
 49          V [B [I]] = . 1 ; // record it needs to rebuild the planet 
50      }
 51 is      int CNT = N- K;
 52 is      // not rebuild we will not be destroyed up to Unicom planet    
 53      // if two planets are present, i.e. when not rebuilt are combined 
54 is      for ( int I = . 1 ; I <= 2 * m; I ++ ) {
 55          IF ( ! V [G [I] .ver] &&! V [G [I]. from ] && GET (G [I]. from )! = GET (G [I] .ver)) {
 56 is             CNT -; Merge (. G [I] from , G [I] .ver);
 57 is          }
 58      }
 59      // from the back to back construction destroy planet 
60      ANS [K + . 1 ] = CNT;
 61 is      for ( int I = K; I> = . 1 ; i-- ) {
 62 is          // count the number of link block 
63 is          CNT ++; V [B [I]] = 0 ;
 64          for ( int J = head [B [I]]; J; J = G [J] .next) {
 65              IF (! V [G [J] .ver] && GET . (G [J] from !) = GET (G [J] .ver)) {
 66                 cnt--;merge(b[i],g[j].ver);
67             }
68         }
69         ans[i]=cnt;
70     }
71     for(int i=1;i<=k+1;i++) printf("%d\n",ans[i]);
72     return 0;
73 }

 

Guess you like

Origin www.cnblogs.com/DarkValkyrie/p/10972868.html