BZOJ4423: [AMPPZ2013]Bytehattan

本文介绍了BZOJ4423:[AMPPZ2013]Bytehattan的问题解决思路,通过使用对偶图和并查集的方法来判断删除特定边是否会导致图中某些顶点变得不连通。具体实现中,文章详细解释了如何通过并查集维护空块之间的联通性,并给出了完整的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

BZOJ4423: [AMPPZ2013]Bytehattan

对偶图·并查集

题解:

http://www.cnblogs.com/lcf-2000/p/6217985.html

  删除一条边可以看做把两个空块连通。当删除一条边时这条边紧邻的两个空块已经连通了,那么删除这条边会导致这条边的两个顶点不连通。

  仔细想想觉得非常有道理。当删除一条边时发现这条边紧邻的两个空块已经连通了,那么删除这条边后会出现一个空块连成的环,于是就把里面的点和外面的点给隔开了。

  之后的事就非常简单了。将空块抠出来,然后并查集维护联通性即可。

Code:

#include <iostream>
#include <cstring>
#include <cstdio>
#define D(x) cout<<#x<<" = "<<x<<"  "
#define E cout<<endl
using namespace std;
const int N = 1500*1500+5;

int n,k,id[1505][1505];

struct MergeSet{
    int pa[N]; 
    void init(int sz){ for(int i=1;i<=sz;i++)pa[i]=i; }
    int find(int x){ if(pa[x]!=x)pa[x]=find(pa[x]); return pa[x]; }
} ms;

void init(){
    for(int i=1;i<=n-1;i++)
        for(int j=1;j<=n-1;j++)
            id[i][j]=(i-1)*(n-1)+j;
}

void getblock(int a,int b,char op,int &x,int &y){
    if(op=='N'){ x=id[a-1][b]; y=id[a][b]; }
    else{ x=id[a][b-1]; y=id[a][b]; }
}

int main(){
    freopen("a.in","r",stdin);
    int a1,a2,a,b1,b2,b,x,y,ans=1; char op[5];
    scanf("%d%d",&n,&k);
    init(); ms.init(n*n);
    for(int i=1;i<=k;i++){
        scanf("%d%d%s",&a1,&b1,op);
        scanf("%d%d%s",&a2,&b2,op+1);
        if(ans)a=a1,b=b1,op[0]=op[0];
        else a=a2,b=b2,op[0]=op[1];
//      D(a); D(b); D(op[0]); E;
        getblock(a,b,op[0],x,y);
//      D(x); D(y); E;
        x=ms.find(x); y=ms.find(y);
        if(x==y)ans=false;
        else ans=true, ms.pa[x]=y;
        printf("%s\n",ans?"TAK":"NIE");
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值