NBOJ 1187 Hole Breaker 并查集

来源:互联网 发布:vue.js 2.0视频 编辑:程序博客网 时间:2024/05/20 00:51

题目来源:http://ac.nbutoj.com/Problem/view.xhtml?id=1187

题意:就是说有一个方阵,然后对小方阵操作,也就是标记小方阵,求最后标记的方阵中能连到一起的方阵最大是多少。能连到一起的条件是至少有一条公共边。

思路:由于有多次询问,每次询问都要输出,做多询问200000次,因此朴素方法的话,肯定会tle。由此想到并查集,对小方阵标记时,查看该小方阵的四周是否有标记的,若有标记的,则用并查集合并到一个集合里面即可。

代码:

#include <iostream>#include <cstdio>#include <string.h>#include <string>using namespace std;#define CLR(arr,val) memset(arr,val,sizeof(arr))const int N = 1001000;int father[N],num[N],flag[N],mmax;int find(int x){int fx = father[x];if(fx == x) return father[x];else{  father[x] = find(father[x]);  return father[x];}}void Unionset(int dit,int value){int fdit = find(dit);int fvalue = find(value);if(fdit != fvalue){  father[fvalue] = fdit;  num[fdit] += num[fvalue];  if(num[fdit] > mmax)     mmax = num[fdit];}return;}int main(){//freopen("1.txt","r",stdin);int n,ask;while(scanf("%d",&n) != EOF){  scanf("%d",&ask);  char ss[3];  for(int i = 0;i < n*n;++i){  father[i] = i;  num[i] = 1;  }  int x,y,up,down,left,right,dit,isnot = 0;  CLR(flag,0);  mmax = 0;  while(ask--){    scanf("%s",ss);if(ss[0] == 'B'){  isnot = 1;  scanf("%d%d",&x,&y);  if(x == 0) dit = y;  else dit = x*n+y;  flag[dit] = 1;  if(x != n-1 && flag[dit+n])  Unionset(dit,dit+n);  if(x != 0 && flag[dit-n])  Unionset(dit,dit-n);  if(y != 0 && flag[dit-1])  Unionset(dit,dit-1);  if(y != n-1 && flag[dit+1])  Unionset(dit,dit+1);}else{ if(mmax == 0 && isnot == 1) printf("1\n"); else    printf("%d\n",mmax);}  }}return 0;}


原创粉丝点击