Farm Irrigation 【HDU - 1198】【并查集+模拟】

好题啊~坏笑


一道典型的并查集的题目,就是加上了模拟的过程会让我感到胆寒~呜呜呜


#include <iostream>
#include <cstdio>
#include <cmath>
#include <string>
#include <cstring>
#include <algorithm>
#include <limits>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#define lowbit(x) ( x&(-x) )
#define pi 3.141592653589793
#define e 2.718281828459045
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
const int maxN=2505;
int N, M, tot, root[maxN];
char mp[maxN];
set<int> st;
void init()
{
    st.clear();
    tot=N*M;
    for(int i=1; i<=tot; i++) root[i]=i;
}
int fid(int x) { return x==root[x]?x:(root[x]=fid(root[x])); }
void mix(int x, int y)
{
    int u=fid(x), v=fid(y);
    if(u!=v) root[u]=v;
}
bool left(int x)        //向左连通
{
    return mp[x]=='A' || mp[x]=='C' || mp[x]=='F' || mp[x]=='G' || mp[x]=='H' || mp[x]=='I' || mp[x]=='K';
}
bool right(int x)
{
    return mp[x]=='B' || mp[x]=='D' || mp[x]=='F' || mp[x]=='G' || mp[x]=='I' || mp[x]=='J' || mp[x]=='K';
}
bool up(int x)
{
    return mp[x]=='A' || mp[x]=='B' || mp[x]=='E' || mp[x]=='G' || mp[x]=='H' || mp[x]=='J' || mp[x]=='K';
}
bool down(int x)
{
    return mp[x]=='C' || mp[x]=='D' || mp[x]=='E' || mp[x]=='H' || mp[x]=='I' || mp[x]=='J' || mp[x]=='K';
}
void solve()
{
    for(int i=1; i<=tot; i++)
    {
        if(mp[i]=='A')
        {
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i-M>0 && down(i-M)) mix(i, i-M);
        }
        else if(mp[i]=='B')
        {
            if(i%M>0 && left(i+1)) mix(i, i+1);
            if(i-M>0 && down(i-M)) mix(i, i-M);
        }
        else if(mp[i]=='C')
        {
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
        }
        else if(mp[i]=='D')
        {
            if(i%M>0 && left(i+1)) mix(i, i+1);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
        }
        else if(mp[i]=='E')
        {
            if(i-M>0 && down(i-M)) mix(i, i-M);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
        }
        else if(mp[i]=='F')
        {
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i%M>0 && left(i+1)) mix(i, i+1);
        }
        else if(mp[i]=='G')
        {
            if(i-M>0 && down(i-M)) mix(i, i-M);
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i%M>0 && left(i+1)) mix(i, i+1);
        }
        else if(mp[i]=='H')
        {
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i-M>0 && down(i-M)) mix(i, i-M);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
        }
        else if(mp[i]=='I')
        {
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i%M>0 && left(i+1)) mix(i, i+1);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
        }
        else if(mp[i]=='J')
        {
            if(i-M>0 && down(i-M)) mix(i, i-M);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
            if(i%M>0 && left(i+1)) mix(i, i+1);
        }
        else
        {
            if(i-M>0 && down(i-M)) mix(i, i-M);
            if(i+M<=tot && up(i+M)) mix(i, i+M);
            if(i%M>1 && right(i-1)) mix(i, i-1);
            if(i%M>0 && left(i+1)) mix(i, i+1);
        }
    }
}
int main()
{
    while(scanf("%d%d", &N, &M)!=EOF)
    {
        if(N<0 && M<0) break;
        init();
        getchar();
        for(int i=1; i<=tot; i++) { scanf("%c", &mp[i]); if(i%M==0) getchar();}
        solve();
        for(int i=1; i<=tot; i++) st.insert(fid(i));
        printf("%d\n", (int)st.size());
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41730082/article/details/83503073