SSL-ZYC 2415 连通块

题目大意:

这里写图片描述
这里写图片描述
这里写图片描述


思路:
并查集
一开始以为是DFS,但是看到每次都要输出联通块的个数,就感觉不对。
可以把相邻的同颜色的块看作同一祖先的块,用sum记录现在有多少个联通块。


代码:

#include <cstdio>
#include <iostream>
using namespace std;

int n,m,a[511][511],father[250101],x,y,sum,c;

int find(int x)
{
    return x==father[x]?x:father[x]=find(father[x]);
}

int l(int x,int y)
{
    return (x-1)*n+y;
}

int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=n*n;i++) father[i]=i;
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&c,&x,&y);
        c++;
        sum++;  //联通块个数加一
        a[x][y]=c;  //记录颜色
        if (x>1&&a[x-1][y]==c&&father[find(l(x,y))]!=find(l(x-1,y))) 
         father[find(l(x,y))]=find(l(x-1,y)),sum--;  
        if (x<n&&a[x+1][y]==c&&father[find(l(x,y))]!=find(l(x+1,y))) 
         father[find(l(x,y))]=find(l(x+1,y)),sum--;
        if (y<m&&a[x][y+1]==c&&father[find(l(x,y))]!=find(l(x,y+1))) 
         father[find(l(x,y))]=find(l(x,y+1)),sum--;
        if (y>1&&a[x][y-1]==c&&father[find(l(x,y))]!=find(l(x,y-1))) 
         father[find(l(x,y))]=find(l(x,y-1)),sum--;  //向四周搜索联通块
        printf("%d\n",sum);
    }
    return 0;
}
posted @ 2018-05-12 14:13  全OI最菜  阅读(84)  评论(0编辑  收藏  举报