SGU 177 Square(并查集)

来源:互联网 发布:淘宝卖保健品店铺名 编辑:程序博客网 时间:2024/05/01 04:15

题意:给出一个n×n的矩阵,矩阵上每个格子最开始都是白色的,给出m个操作,每个操作会把一个矩形染成黑色或白色,问最后有多少个白的格子。

思路:这题让我不禁想起了poj 2528,这类的染色问题应该都能用并查集搞……从后往前处理操作,这样已经画过的地方就不会第二次被染色,然后把染过的标记一下,接下来就是用并查集把染过的“跳过去”就好了,在这个过程中统计一下染过的黑色格子的数量,用总量一减就OK了~不过按这题的数据量来看,线段树应该也是完全没问题的……


代码:


#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<algorithm>#include<map>#include<queue>#include<set>#include<stack>#include<cmath>#include<vector>#define inf 0x3f3f3f3f#define Inf 0x3FFFFFFFFFFFFFFFLL#define eps 1e-9#define pi acos(-1.0)using namespace std;typedef long long ll;const int maxn=1000+10;int parents[maxn][maxn];bool vis[maxn][maxn];int Find(int r,int x){    return parents[r][x]==x?x:parents[r][x]=Find(r,parents[r][x]);}struct Paint{    int x1,y1,x2,y2;    int colors;    void readit()    {        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);    }    void change()    {        if(x1>x2) swap(x1,x2);        if(y1>y2) swap(y1,y2);    }}paints[maxn*5];int main(){    //freopen("in.txt","r",stdin);    //freopen("out.txt","w",stdout);    int n,m;    scanf("%d%d",&n,&m);    char str[5];    for(int i=0;i<m;++i)    {        paints[i].readit();        paints[i].change();        scanf("%s",str);        if(str[0]=='b') paints[i].colors=1;        else paints[i].colors=0;    }    for(int i=1;i<=n;++i)      for(int j=1;j<=n;++j)         parents[i][j]=j;    memset(vis,0,sizeof(vis));    int total=n*n;    int now,f;    for(int i=m-1;i>=0;--i)    {        for(int j=paints[i].x1;j<=paints[i].x2;++j)        {            now=paints[i].y1;            while(now<=paints[i].y2)            {                f=Find(j,now);                if(f==now&&!vis[j][now])                {                    vis[j][now]=true;                    parents[j][now]=paints[i].y2;                    if(paints[i].colors) total--;                    now++;                }                else now=f+1;            }        }    }    printf("%d\n",total);    return 0;}


原创粉丝点击