zoukankan      html  css  js  c++  java
  • 八中教室的灯加强版 【并查集】

    本人水平有限,题解不到为处,请多多谅解

    本蒟蒻谢谢大家观看

    题目:

    八中教室的灯加强版

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 79  Solved: 38
    [Submit][Status][Web Board]

    Description

    八中一共有被用M条双向道路连接的N个教室(1<=N,M<=3000)。为了关闭整个八中,master wen 计划每一次关
    闭掉一个教室。当一个教室被关闭了,所有的连接到这个教室的道路都会被关闭,而且再也不能够被使用。master
     wen现在正感兴趣于知道在每一个时间(这里的“时间”指在每一次关闭教室之前的时间)时他的八中是否是“全
    连通的”——也就是说从任意的一个开着的教室开始,能够到达另外的一个教室。注意自从某一个时间之后,可能
    整个八中都开始不会是“全连通的”。

    Input

    第一行给出数字N,M,代表有N个教室,M条边,1<=N,M<=200000
    接下来N行来用描述教室之间相连的情况
    接下来N行,每行给出一个数字,代表关闭了哪个教室的灯

    Output

    输出N行,每行输出"YES"或"NO".
    第一行输出最开始时整个八中是不是连通的
    后面的N-1用来描述关闭某个教室的灯后,八中是不是连通的。

    Sample Input

    4 3
    1 2
    2 3
    3 4
    3
    4
    1
    2

    Sample Output

    YES
    NO
    YES
    YES

    HINT

    题目大意:

    给你n个点和m条边,每次删掉一个点(被删的点就永久消失),并且与这个点相连的边也被删掉,现求删除这个点后,场上的所有点是否还能连通。
    题目解析:

    如果要边输入边删点的话,那么肯定要构造一棵树,并且还要找删点后一个还未删的点去进行搜索,看整个图是否连通,如果数据小还好,但如果数据大的话,肯定会超时。
    那么我们换一种思路,既然是看整个图是否连通,那么是不是看每一个的根结点是否一致,那么最好的方法就是使用并查集,为了使时间复杂度更小,我们可以使之扁平化(但好像正着搜没有什么作用,因为每次是删头结点,并不是连接两点),但若使用并查集的话,每次搜索还是要搜寻每个点的根节点,并且还要判断每一条边能不能走,这也一定会超时,那如果每次不遍历每一个点,那是否就能不超时呢?
    其实要做到这一点也不难,我们不如反向思维是不是从开头每次删一个点直至删完,就相当于从后面做每次加一个点直至补完,并且从结尾往前加点,那么每次符合条件的边就不可能变动(就不用考虑之前连接的两点是否连通),并且每一个节点的根就只会连到另一个节点上,扁平化就更能体现作用。
    但现在还是没有解决遍历点的问题及遍历边的问题(重中之重,打起精神来,注意!)
    遍历点的问题:是不是每加一个点,就相当于多了一个连通块,而每把两个根节点不相同的连通块相连就少了一个根节点,若要使整个图为一个环形,则整个图为一个连通块。
    遍历边的问题:既然点是按先后顺序出现的,而边的出现是看两头的点是否出现,若按平常的话,一定要去搜索,在这里我们只需排序即可。我们先记录下每一个点出现的先后排名,然后记录下每一条边的两个端点,最后按照每条边的端点出现的先后排序即可(记得按每条边的最晚出现的点与对方做比较)。我们回到程序中,在搜的时候只要看当前的边是否符合条件,若符合,则把条的两端点的根相连,若不符合,则不往下继续搜
     
     
    code:
     1 #include<bits/stdc++.h>
     2 #pragma GCC optimize(3)
     3 const int N=200001;
     4 using namespace std;
     5 int n,m,tot;
     6 int ver[N*2],nxt[N*2],head[N],f[N],k[N];
     7 int sum;
     8 bool flag[N];
     9 bool ans[N];
    10 void inint(){
    11     freopen("light.in","r",stdin);
    12     freopen("light.out","w",stdout);
    13 }
    14 inline int read(){
    15     int x=0,f=1;char ch=getchar();
    16     while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    17     while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    18     return x*f;
    19 }
    20 inline void write(int x)
    21 {
    22     if(x<0)x=-x,putchar('-');
    23     if(x>9)write(x/10);
    24     putchar(x%10+'0');
    25 }
    26 void add(int x,int y){
    27     ++tot;
    28     ver[tot]=y;
    29     nxt[tot]=head[x];
    30     head[x]=tot;
    31 }
    32 int find(int fa){
    33     if(f[fa]==fa)return fa;
    34     return f[fa]=find(f[fa]);
    35 }
    36 int main()
    37 {
    38     //inint();
    39     n=read(),m=read();
    40     for(int i=1;i<=n;i++){
    41         f[i]=i;
    42     }
    43     for(int i=1,x,y;i<=m;i++){
    44         x=read(),y=read();
    45         add(x,y);
    46         add(y,x);
    47     }
    48     for(int i=1;i<=n;i++){
    49         k[i]=read();
    50     }
    51     for(int i=n;i>=1;i--){
    52         sum++;
    53         flag[k[i]]=true;
    54         for(int j=head[k[i]];j;j=nxt[j]){
    55             int y=ver[j];
    56             if(flag[y]&&find(y)!=find(k[i])){
    57                 f[find(y)]=f[find(k[i])];
    58                 sum--;
    59             }
    60         }
    61         if(sum==1)ans[i]=true;
    62     }
    63     for(int i=1;i<=n;i++){
    64         if(ans[i])printf("YES
    ");
    65         else printf("NO
    ");
    66     }
    67     return 0;
    68 }
    69 /*
    70 4 3
    71 1 2
    72 2 3
    73 3 4
    74 3
    75 4
    76 1
    77 2
    78 */
     

     

  • 相关阅读:
    Windows Server 2008取消登录前的Ctrl+Alt+Delete组合键操作
    Kali Linux远程连接Windows服务器
    Kali Linux虚拟机安装完整安装过程及简单配置(视频)
    Kali Linux中下载工具Axel的安装和使用
    2017年Kali Linux更新源
    解决VMware虚拟机报错“无法连接MKS:套接字连接尝试次数太多,正在放弃”
    .deb软件包的安装和软件的卸载
    解决C语言程序报错:return type defaults to‘int’
    解决BackBox中Fcitx输入法中文输入状态下不显示候选词框的问题
    导航狗信息导航网站首页源代码(2017年11月03日版)
  • 原文地址:https://www.cnblogs.com/nlyzl/p/11776244.html
Copyright © 2011-2022 走看看