• 【BZOJ4423】Bytehattan(AMPPZ2013)-对偶图+并查集


    测试地址:Bytehattan
    做法:本题需要用到对偶图+并查集。
    因为是不断删边,而且强制在线,所以直接维护格点的连通性不现实。我们发现网格图是个平面图,所以对偶图的连通性应该和原图的连通性有关,于是我们从对偶图的角度去思考。
    首先,在原图中是删边的操作,在对偶图中就是连边了,这个性质非常好。其次,我们询问的是每次删除的边的两个端点的连通性,有这样一个结论:如果在对偶图中加上这条边后,对偶图中形成了一个环(即两个点在加边前就连通),这两个点就不连通,反之就连通。这应该比较明显,因为如果形成了一个环,那么两个端点中一定有一个包在环内,另一个在环外,显然就不连通了。
    于是经过了这样的转化后,用并查集简单维护即可,时间复杂度为O(n2)
    以下是本人代码:

    #include <bits/stdc++.h>
    using namespace std;
    int n,m,fa[3000010];
    
    int point(int a,int b)
    {
        if (a<=0||b<=0||a>=n||b>=n) return 0;
        return (a-1)*(n-1)+b;
    }
    
    int find(int x)
    {
        int r=x,i=x,j;
        while(r!=fa[r]) r=fa[r];
        while(i!=r) j=fa[i],fa[i]=r,i=j;
        return r;
    }
    
    void merge(int x,int y)
    {
        int fx=find(x),fy=find(y);
        fa[fx]=fy;
    }
    
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<=(n-1)*(n-1);i++)
            fa[i]=i;
    
        bool flag=0;
        for(int i=1;i<=m;i++)
        {
            int a,b,la,lb;
            char k,lk;
            scanf("%d%d %c%d%d %c",&a,&b,&k,&la,&lb,&lk);
            if (flag) a=la,b=lb,k=lk;
    
            int fx,fy;
            if (k=='N') fx=find(point(a-1,b)),fy=find(point(a,b));
            else fx=find(point(a,b-1)),fy=find(point(a,b));
            if (fx==fy) flag=1;
            else merge(fx,fy),flag=0;
            printf("%s
    ",flag?"NIE":"TAK"); 
        }
    
        return 0;
    }
  • 相关阅读:
    一次郁闷的项目部署经历
    一道面试题的求解
    一次惨痛的教训
    小地方,大郁闷001
    WPF相对资源的访问
    VS2008安装时提示磁盘空间不够的解决办法
    WPFSlider 控件的使用
    关于asp.net大文件上传和进度条实现的学习(1)
    DataList的一次分页困惑
    关于android的XML的解析
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793325.html
Copyright © 2020-2023  润新知