zoukankan      html  css  js  c++  java
  • HDU_1198 Farm Irrigation(并查集)

      

    /*
    开始思路想错了,直接用并查集把输入的square并到并查集里边了,后来想到可能一种
    square连续出现多次,这样直接合并肯定会出问题的。然后就一直再想其他思路,昨晚睡觉时突
    然想到可以给这些square重新编号,把对应的square的pipes type继承过来,然后再用
    并查集合并。最终以6A告终。不容易啊,大牛鄙视我吧。
    */

    #include
    <iostream>
    #include
    <cstdio>
    #include
    <cstring>

    using namespace std;

    const int N = 3000;

    class pipes
    {
    public:
    int l; //左边节
    int r; //右边界
    int u; //上边界
    int d; //下边界
    }tmp[12], num[N];

    int parent[N];
    int rank[N];
    int map[55][55];

    void init() //记录11种 pipes type。
    {
    for(int i = 1; i <= 11; i++)
    {
    tmp[i].l
    = 0;
    tmp[i].r
    = 0;
    tmp[i].u
    = 0;
    tmp[i].d
    = 0;
    }

    tmp[
    1].l = 1;
    tmp[
    1].u = 1;

    tmp[
    2].r = 1;
    tmp[
    2].u = 1;

    tmp[
    3].l = 1;
    tmp[
    3].d = 1;

    tmp[
    4].r = 1;
    tmp[
    4].d = 1;

    tmp[
    5].u = 1;
    tmp[
    5].d = 1;

    tmp[
    6].l = 1;
    tmp[
    6].r = 1;

    tmp[
    7].l = 1;
    tmp[
    7].r = 1;
    tmp[
    7].u = 1;

    tmp[
    8].l = 1;
    tmp[
    8].u = 1;
    tmp[
    8].d = 1;

    tmp[
    9].l = 1;
    tmp[
    9].r = 1;
    tmp[
    9].d = 1;

    tmp[
    10].u = 1;
    tmp[
    10].r = 1;
    tmp[
    10].d = 1;

    tmp[
    11].l = 1;
    tmp[
    11].r = 1;
    tmp[
    11].u = 1;
    tmp[
    11].d = 1;
    }

    int find(int x) //并查集非递归路径压缩查找,个人习惯这样写,因为递归的路径压缩可能会Ovre Stack(只是可能,大牛勿喷。。。)
    {
    int k, r, j;
    r
    = x;
    while(r != parent[r])
    r
    = parent[r];
    k
    = x;
    while(k != r)
    {
    j
    = parent[k];
    parent[k]
    = r;
    k
    = j;
    }
    return r;
    }

    void Union(int a, int b) //合并
    {
    int x = find(a);
    int y = find(b);

    if(x == y) return;

    if(rank[x] > rank[y])
    parent[y]
    = x;
    else
    {
    parent[x]
    = y;
    if(rank[x] == rank[y])
    ++rank[y];
    }
    }

    int main()
    {
    //freopen("data.in", "r", stdin);

    int n, m;
    init();
    while(scanf("%d%d", &n, &m) != EOF)
    {
    if(n < 0 || m < 0)
    break;
    getchar();
    char c;
    int x = 1, t, i, j;
    for(i = 1; i <= n; i++)
    {
    for(j = 1; j <= m; j++)
    {
    scanf(
    "%c", &c);
    t
    = c-'A'+1;
    map[i][j]
    = x; //重新编号,起始号为1
    num[x].l = tmp[t].l; //继承对应的 pipes type
    num[x].r = tmp[t].r;
    num[x].u
    = tmp[t].u;
    num[x].d
    = tmp[t].d;
    x
    ++;
    }
    getchar();
    }

    /*for(i = 1; i <= n; i++)
    {
    for(j = 1; j <= m; j++)
    printf("%d ", map[i][j]);
    printf("\n");
    }
    */

    for(i = 1; i <= n; i++)
    for(j = 1; j <= m; j++)
    {
    parent[map[i][j]]
    = map[i][j]; //初始化parent[],rank[];
    rank[map[i][j]] = 0;
    }
    for(i = 1; i <= n; i++)
    {
    for(j = 1; j <= m; j++)
    {
    if(num[map[i][j]].l == num[map[i][j-1]].r && num[map[i][j]].l != 0 && j > 1) //左边
    Union(map[i][j], map[i][j-1]);

    if(num[map[i][j]].r == num[map[i][j+1]].l && num[map[i][j]].r != 0 && j+1 <= m) //右边
    Union(map[i][j], map[i][j+1]);

    if(num[map[i][j]].u == num[map[i-1][j]].d && num[map[i][j]].u != 0 && i > 1) //上边
    Union(map[i][j], map[i-1][j]);

    if(num[map[i][j]].d == num[map[i+1][j]].u && num[map[i][j]].d != 0 && i+1 <= n) //下边
    Union(map[i][j], map[i+1][j]);
    }
    }
    int cnt = 0;
    for(i = 1; i <= n; i++)
    for(j = 1; j <= m; j++)
    if(find(map[i][j]) == map[i][j]) //统计个数
    cnt++;
    printf(
    "%d\n", cnt);
    }
    return 0;
    }
  • 相关阅读:
    [linux] SIGPIPE信号处理
    巧妙使用spring对commons fileUpload的包装
    对commons fileupload组件的简单封装
    利用脚本启动java程序
    [linux] 创建daemon进程
    利用Jakarta commons fileupload组件实现多文件上传
    dedeCms下面 arclist标签无法嵌套图片(img)之解决办法
    编程乱码问题初步探索
    PHP下载文件函数
    Windows7下IIS中以FastCgi安装PHP
  • 原文地址:https://www.cnblogs.com/vongang/p/2173003.html
Copyright © 2011-2022 走看看