• 1015: [JSOI2008]星球大战starwar


    1015: [JSOI2008]星球大战starwar

    Time Limit: 3 Sec  Memory Limit: 162 MB
    Submit: 3001  Solved: 1321
    [Submit][Status]

    Description

    很久以前,在一个遥远的星系,一个黑暗的帝国靠着它的超级武器统治者整个星系。某一天,凭着一个偶然的机遇,一支反抗军摧毁了帝国的超级武器,并攻下了星系中几乎所有的星球。这些星球通过特殊的以太隧道互相直接或间接地连接。 但好景不长,很快帝国又重新造出了他的超级武器。凭借这超级武器的力量,帝国开始有计划地摧毁反抗军占领的星球。由于星球的不断被摧毁,两个星球之间的通讯通道也开始不可靠起来。现在,反抗军首领交给你一个任务:给出原来两个星球之间的以太隧道连通情况以及帝国打击的星球顺序,以尽量快的速度求出每一次打击之后反抗军占据的星球的连通快的个数。(如果两个星球可以通过现存的以太通道直接或间接地连通,则这两个星球在同一个连通块中)。

    Input

    输入文件第一行包含两个整数,N (1 <= N <= 2M) 和M (1 <= M <= 200,000),分别表示星球的数目和以太隧道的数目。星球用0~N-1的整数编号。接下来的M行,每行包括两个整数X, Y,其中(0<=X<>Y

    Output

    输出文件的第一行是开始时星球的连通块个数。接下来的N行,每行一个整数,表示经过该次打击后现存星球的连通块个数。

    Sample Input

    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

    Sample Output

    1
    1
    1
    2
    3
    3

    HINT

     

    Source

     题解:正如JSZKC神犇所言——既然并查集不能合并,那么倒着插入不就行了?于是乎我这么做了一下,结果是70分,TLE。。。然后我只好找网上的标程,结果发现了人家在并查集里面有个异常强悍的优化(具体见程序里面的getfat函数),然后就擦着边AC了。。。具体做法是——先把所有边里面没有涉及到被删除点的全部合并,然后按照删点顺序倒着来合并,这一路每次要记录下连通块数量。。。(注意:最后输出时要-i+1,因为假如举个例子,所有的星球在最后的数据中都被干掉了的话,那么假如单纯是连通块的话,应该有N个才是,可是事实上一个星球都没了。。。)
     
     1 type point=^node;
     2      node=record
     3                 g:longint;
     4                 next:point;
     5      end;
     6 var
     7    i,j,k,l,m,n,t:longint;
     8    a:array[0..400000] of point;
     9    c,b,d,e:array[0..400000] of longint;
    10    p:point;
    11 function getfat(x:longint):longint;inline;
    12          begin
    13               if x<>c[x] then
    14                  begin
    15                       c[x]:=getfat(c[x]);  //orz强悍的优化
    16                  end;
    17               exit(c[x]);
    18          end;
    19 function tog(x,y:longint):boolean;inline;
    20          begin
    21               exit(getfat(x)=getfat(y));
    22          end;
    23 procedure merge(x,y:longint);inline;
    24           begin
    25                c[getfat(x)]:=getfat(y);
    26           end;
    27 procedure add(x,y:longint);inline;
    28           var p:point;
    29           begin
    30                new(p);
    31                p^.g:=y;
    32                p^.next:=a[x];
    33                a[x]:=p;
    34           end;
    35 begin
    36      readln(n,m);
    37      for i:=1 to n do
    38          begin
    39               c[i]:=i;
    40               a[i]:=nil;
    41          end;
    42      for i:=1 to m do
    43          begin
    44               readln(j,k);
    45               add(j+1,k+1);add(k+1,j+1);
    46          end;
    47      fillchar(b,sizeof(b),0);
    48      readln(t);
    49      for i:=1 to t do
    50          begin
    51               readln(d[i]);
    52               d[i]:=d[i]+1;
    53               b[d[i]]:=1;
    54          end;
    55      l:=n;
    56      for i:=1 to n do
    57          begin
    58               if b[i]=0 then
    59                  begin
    60                       p:=a[i];
    61                       while p<>nil do
    62                             begin
    63                                  if b[p^.g]=0 then
    64                                     begin
    65                                          if not(tog(i,p^.g)) then
    66                                             begin
    67                                                  dec(l);merge(i,p^.g);
    68                                             end;
    69                                     end;
    70                                  p:=p^.next;
    71                             end;
    72                  end;
    73          end;
    74      e[t+1]:=l;
    75      for i:=t downto 1 do
    76          begin
    77               b[d[i]]:=0;
    78               p:=a[d[i]];
    79               while p<>nil do
    80                     begin
    81                          if b[p^.g]=0 then
    82                             begin
    83                                  if not(tog(d[i],p^.g)) then
    84                                     begin
    85                                          merge(d[i],p^.g);
    86                                          dec(l);
    87                                     end;
    88                             end;
    89                          p:=p^.next;
    90                     end;
    91               e[i]:=l;
    92          end;
    93      for i:=1 to t+1 do writeln(e[i]-i+1);
    94 end.     
  • 相关阅读:
    easyui combobox 的取值问题
    关于Java中集合的讲解~
    面试中经常会被问到的70个问题
    80端口被NT kernel & System 占用pid 4
    java中try{}catch{}和finally{}的执行顺序问题
    Java中基本数据类型的存储方式和相关内存的处理方式(java程序员必读经典)
    String,StringBuffer和StringBuilder三者的讲解
    String是基本的数据类型吗?
    jdk中那些常见的类不能被继承的
    关于java中getClass()和getSuperClass()的讲解
  • 原文地址:https://www.cnblogs.com/HansBug/p/4175836.html
Copyright © 2020-2023  润新知