zoukankan      html  css  js  c++  java
  • NKOJ P3696 假期关楼 (并查集)

    时间限制 : - MS   空间限制 : 65536 KB
    评测说明 : 因文件输入输出过大,时限2000ms
    问题描述

    暑假到了,大部分学生都回家了,只有少量竞赛学生还在学校里。
    学校打算逐步把教学楼都关闭。以减少运营成本。
    学校里的N栋教学楼(编号1到N)通过M条双向道路连接起来。每关闭了一栋楼,与该楼相连的所有道路同时都会被关闭。
    何老板想知道,学校每关闭一栋楼,剩下的处于开放状态的教学楼是否是连通的。连通就是指任何两个开放的楼都可以相互到达。
    注意,有可能一开始所有楼都不连通。

    输入格式

    第一行,一个两个整数N和M
    接下来M行,每行两个整数x和y,表示x、y两栋楼间有道路直接相连。
    接下来N行,每行一个整数代表一栋楼的编号。整个N行数字表示依次关闭的教学楼的顺序。

    输出格式

    共N行,每行是"YES"或者"NO",若剩下的楼是连通的输出YES,否则输出NO。
    其中第1行表示一开始整个学校的楼是否连通。
    其中第i+1行表示第i次关闭教学楼后,剩下的楼是否连通。

    样例输入

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

    样例输出

    YES
    NO
    YES
    YES

    提示

    对于40%的数据1≤N,M≤3000   

    对于100%的数据1≤N,M≤200000

     
    为我当时智障用kruskal 判断 道路是否联通 而 自闭
     
    按顺序关 判断集合 可以反向考虑  删边看作加边 
    每次联通块加1 判断当前新加的点 是否可以与已经在集合里面的点 合并 如果合并 ans++;
    如果原联通块-ans==1 则可行
    否则就不行
     
    code:
    //
    #include<bits/stdc++.h>
    using namespace std;
    int n,m;
    #define maxnn 600000
    int f[maxnn];
    int ans[maxnn],shun[maxnn];
    int sec=0;
    int sta[maxnn],nex[maxnn],en[maxnn],tot,las[maxnn];
    int mark[maxnn];
    
    int  gf(int v)
    {
        return f[v]==v? v:f[v]=gf(f[v]);
    }
    void add(int a,int b)
    {
        en[++tot]=b;
        nex[tot]=las[a];
        las[a]=tot;
        sta[tot]=a;
    }
    int  judge(int v)
    {
        int ans=0;
        mark[v]=1;
        for(int i=las[v];i;i=nex[i])
        {
            int y=en[i];
            if(mark[y])
            {
                if(gf(y)!=gf(v))
                {
                    ans++;
                    f[gf(y)]=gf(v);
                }
            }
        }
        return ans;
    }
    int main()
    {
        scanf("%d%d",&n,&m);    
        int x,y;
        for(int i=1;i<=n;i++)
        {
            f[i]=i;
        }
        for(int i=1;i<=m;i++)
        {
            scanf("%d%d",&x,&y);
            add(x,y);
            add(y,x);
        }
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&shun[i]);
        }
        for(int i=n;i>=0;i--)
        {
            sec++;
            sec-=judge(shun[i]); 
            if(sec==1)
            ans[i]=1;
            else
            ans[i]=0;
        }    
        for(int i=1;i<=n;i++)
        {
            if(ans[i]==1)
            printf("YES
    "); 
            else
            printf("NO
    "); 
        }
        
        
        
        
    }
    刀剑映出了战士的心。而我的心,漆黑且残破
  • 相关阅读:
    c# 动态加载工具栏按钮代码
    根据结果集处理工作事务c#源码
    关于升级后药库中报表需要重新设置的问题
    vs2005打开工程后退出
    把照片写入到DataTable
    关于导入最新住院管理后界面控件乱的问题
    django实战2运维日常维护统计
    ip_conntrack_netbios_n 报错
    django_book学习笔记7django常用方法总结
    python模块整理14re模版
  • 原文地址:https://www.cnblogs.com/OIEREDSION/p/11260285.html
Copyright © 2011-2022 走看看