Codeforces325 D【并查集维护连通性】

参考:大牛blog

思路:

因为是环,所以可以复制一下图,先判断一下和他是不是和与他相邻的8个之一的一个障碍使得构成了一个环,环就是一个连通,用并查集维护即可;

如果没有就ans++,然后并把这个点加入。

大致意思就是这样。

#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cstdlib>
#include <ctime>
#include <cmath>
#include <map>
#include <set>
using namespace std;

const int maxn=3000*3000*2+100;
const int dx[8]={-1, -1, -1, 0, 0, 1, 1, 1};
const int dy[8]={-1, 0, 1, -1, 1, -1, 0, 1};

int n, r, c, ti;
int ans;
int fa[maxn];
bool vis[3010][6010];
int mark[maxn];

int find(int cur)
{
    if (fa[cur]<0) return cur;
    else return (find(fa[cur]));
}
void Union(int u, int v)
{
    u=find(u);
    v=find(v);
    if (u==v) return;
    if (fa[u]>fa[v]) swap(u, v);
    fa[u]+=fa[v];
    fa[v]=u;
}
bool check(int &x1, int &y1)
{
    if (x1<1 || x1>r) return false;
    if (y1==0) y1=c;
    else if (y1>c) y1=1;
    if (!vis[x1][y1]) return false;
    return true;
}
void merge(int x, int y)
{
    int nid=(x-1)*c+y;
    for (int i=0; i<8; ++i)
    {
        int x1=x+dx[i];
        int y1=y+dy[i];
        if (check(x1, y1)) Union(nid, (x1-1)*c+y1);
    }
}
bool get_list(int x, int y, int id)
{
    for (int i=0; i<8; ++i)
    {
        int x1=x+dx[i];
        int y1=y+dy[i];
        if (!check(x1, y1)) continue;
        int tmp=find((x1-1)*c+y1);
        if (id && mark[tmp]==ti-1) return false;
        mark[tmp]=ti;
    }
    return true;
}

void solve()
{
    if (c==1) return;
    c*=2;

    for (int i=1; i<=r; ++i)
        for (int j=1; j<=c; ++j)
            fa[(i-1)*c+j]=-1;

    for (int i=1; i<=n; ++i)
    {
        int x, y;
        scanf("%d%d", &x, &y);
        ++ti;
        get_list(x, y, 0);
        ++ti;
        bool flag=get_list(x, y+c/2, 1);
        if (!flag) continue;
        ++ans;
        merge(x, y);
        merge(x, y+c/2);
        vis[x][y]=true;
        vis[x][y+c/2]=true;
    }
}

int main()
{
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
    scanf("%d%d%d", &r, &c, &n);
    solve();
    printf("%d
", ans);
    return 0;
}


原文地址:https://www.cnblogs.com/keyboarder-zsq/p/6777501.html