• 逆向并查集 HYSBZ1015星球大战starwar


     星球大战starwar

     HYSBZ - 1015 
     

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

    Input

      输入文件第一行包含两个整数,N (1  < =  N  < =  2M) 和M (1  < =  M  < =  200,000),分别表示星球的
    数目和以太隧道的数目。星球用 0 ~ N-1的整数编号。接下来的M行,每行包括两个整数X, Y,其中(0 < = X <> 
    Y 表示星球x和星球y之间有“以太”隧道,可以直接通讯。接下来的一行为一个整数k,表示将遭受攻击的星球的
    数目。接下来的k行,每行有一个整数,按照顺序列出了帝国军的攻击目标。这k个数互不相同,且都在0到n-1的范
    围内。

    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
     
    第一次做这种题真的很难想,主要是不敢下手,在网上找了好多解析都是一言概之。还是觉得不要怕错,要自己按自己的思路写一下,发现其实还蛮简单的。
    但感觉自己写的耗时有点多......
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<vector>
     6 #include<stack>
     7 #include<algorithm>
     8 using namespace std;
     9 #define N 400002
    10 #define T(){printf("^^^ ");}
    11 int bc[N], waitdel[N], vis[N], ans[N];;
    12 vector<int>gra[N];
    13 int find(int son)
    14 {
    15     int fa = son;
    16     while(fa != bc[fa])
    17     {
    18         fa = bc[fa];
    19     }
    20     //
    21     int temp = son,k;
    22     while(fa != bc[temp])
    23     {
    24         k = bc[temp];
    25         bc[temp] = fa;
    26         temp = k;
    27     }
    28     return fa;
    29 }
    30  
    31 int main()
    32 {
    33     int n,m,k,x,y;
    34     cin>>n>>m;
    35     for(int i=0; i<m; i++)
    36     {
    37         scanf("%d%d",&x,&y);
    38         gra[x].push_back(y);
    39         gra[y].push_back(x);
    40     }
    41     scanf("%d",&k);
    42     memset(vis,0,sizeof(vis));
    43     for(int i=0; i<k; i++)
    44     {
    45         scanf("%d",&waitdel[i]);
    46         vis[waitdel[i]] = 1;
    47     }
    48     for(int i=0; i<n; i++) bc[i] = i;
    49     int tot = n - k;
    50     for(int i=0; i<n; i++)
    51     {
    52         if(!vis[i])
    53         {
    54             for(int j=0; j<gra[i].size(); j++)
    55             {
    56                 if(!vis[gra[i][j]])
    57                 {
    58                     int x = find(i);
    59                     int y = find(gra[i][j]);
    60                     if(x != y)
    61                     {
    62                         tot --;
    63                         bc[y] = x;
    64                     }
    65                 }
    66             }
    67         }
    68     }
    69     int top = 0;
    70     for(int i=k-1; i>=0; i--)
    71     {
    72         int k = waitdel[i];
    73         ans[top ++] = tot;
    74         tot ++;
    75         for(int j=0; j<gra[k].size(); j++)
    76         {
    77             if(!vis[gra[k][j]])
    78             {
    79                 int x = find(k);
    80                 int y = find(gra[k][j]);
    81                 if(x != y)
    82                 {
    83                     tot --;
    84                     bc[y] = x;
    85                 }
    86             }
    87             vis[k] = 0;
    88         }
    89     }
    90     ans[top++] = tot;
    91     for(int i=top-1; i>=0; i--) printf("%d
    ",ans[i]);
    92 }
  • 相关阅读:
    SpringMVC-注解式控制器详解-SpringMVC强大的数据绑定(1)
    SpringMVC-注解式控制器详解-SpringMVC强大的数据绑定
    关于BI商业智能的“8大问”|一文读懂大数据BI
    关于BI商业智能的“8大问”|一文读懂大数据BI
    符号表
    高性能MYSQL读书笔记1
    perl 打包成PAR包 类似JAR包
    perl 包函数变动 需要重新打包
    第一章 数据引用与匿名存储
    换部门与看录像——北漂18年(90)
  • 原文地址:https://www.cnblogs.com/liwenchi/p/7259255.html
Copyright © 2020-2023  润新知