hdu1198(并查集)

Farm Irrigation

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 7080    Accepted Submission(s): 3041

Problem Description

Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked from A to K, as Figure 1 shows.


Figure 1

Benny has a map of his farm, which is an array of marks denoting the distribution of water pipes over the whole farm. For example, if he has a map

ADC
FJK
IHE

then the water pipes are distributed like


Figure 2

Several wellsprings are found in the center of some squares, so water can flow along the pipes from one square to another. If water flow crosses one square, the whole farm land in this square is irrigated and will have a good harvest in autumn.

Now Benny wants to know at least how many wellsprings should be found to have the whole farm land irrigated. Can you help him?

Note: In the above example, at least 3 wellsprings are needed, as those red points in Figure 2 show.

Input

There are several test cases! In each test case, the first line contains 2 integers M and N, then M lines follow. In each of these lines, there are N characters, in the range of ‘A‘ to ‘K‘, denoting the type of water pipe over the corresponding square. A negative M or N denotes the end of input, else you can assume 1 <= M, N <= 50.

Output

For each test case, output in one line the least number of wellsprings needed.

Sample Input

2 2
DK
HF

3 3
ADC
FJK
IHE

-1 -1

Sample Output

2
3

#include <iostream>
#include <memory.h>
#include <stdio.h>
using namespace std;
char input[50][50];
int parent[2500];
bool vis[2500];
int ans,N,M;
int Init()
{
    for(int i=(N+1)*(M+1);i>=0;i--)
        parent[i]=i;
}
//将字母对应的图案按照上右下左的顺序是否有接口压缩成为二进制对应位是否有1,最高位代表上
int change(char ch)
{
    switch(ch)
    {
        case ‘A‘:return 9;
        case ‘B‘:return 12;
        case ‘C‘:return 3;
        case ‘D‘:return 6;
        case ‘E‘:return 10;
        case ‘F‘:return 5;
        case ‘G‘:return 13;
        case ‘H‘:return 11;
        case ‘I‘:return 7;
        case ‘J‘:return 14;
        case ‘K‘:return 15;
    }
}
//查找父节点的操作,并做路径压缩
int findP(int x)
{
    if(parent[x]==x)
        return x;
    else
    {
        parent[x]=findP(parent[x]);
        return parent[x];
    }
}
void Union(int x,int y)
{
    int xp=findP(x),yp=findP(y);
    parent[yp]=xp;
    return;
}
int main()
{
    freopen("in.in","r",stdin);
    while(~scanf("%d%d",&N,&M)&&N!=-1)
    {
        getchar();
        Init();
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<M;j++)
            {
                scanf("%c",&input[i][j]);
                input[i][j]=change(input[i][j]);
                //查看这一点是否可以和上相邻联通
                if(i>0&&((input[i][j]>>3)&(input[i-1][j]>>1)&1))
                {
                    Union(i*M+j,(i-1)*M+j);
                }
                //查看这一点是否可以和左相邻联通
                if(j>0&&((input[i][j-1]>>2)&input[i][j]&1))
                {
                    Union(i*M+j,i*M+j-1);
                }
            }
            getchar();
        }
        ans=0;
        memset(vis,0,sizeof(vis));
        //检查本点父亲是否已被计算过,本点父亲没被计算过说明本点父亲代表的分量需要一个“源“,并修改本点父亲为已经计算过
        for(int i=0;i<N;i++)
        {
            for(int j=0;j<M;j++)
            {
                if(!vis[findP(i*M+j)])
                {
                   vis[findP(i*M+j)]=true;
                   ans++;
                }
            }
        }
        cout<<ans<<endl;
    }
    return 0;
}

  

时间: 2024-10-10 13:47:06

hdu1198(并查集)的相关文章

详解并查集

详解并查集  Powered by WSY in SSF    2019-11-02  13:46 [1]并查集的定义:   并查集(Disjoint  Set)是一种非常精巧的非常实用的数据结构,它主要用来处理一些不相交集合的合并问题,经典的例子有联通子图,最小生成树的克鲁斯-卡尔算法. [2]并查集的经典问题:   我们通常使用“帮派”.“团伙”等问题举例说明并查集.例如帮派问题: 在某城市里住着n个人,任何两个认识的人不是朋友就是敌人,而且满足: 1. 我朋友的朋友是我的朋友: 2. 我敌

HDU1198水管并查集Farm Irrigation

Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pipes, which is marked

并查集应用hdu1198

就是给并查集换了个形式 判断是否能连接那我写的比较麻烦 可以用四个字符表示四个方向 01开关 判断的时候只需要判断两个方向 一开始感觉无从想法 一步步顺着想有些还是会变简答的 #include<cstdio> #include<algorithm> using namespace std; char a[51][51]; int sett[2500 + 50]; int find2(int x) { while(x!=sett[x] ) x=sett[x]; return x; }

HDU--1198 Farm Irrigation (并查集做法+DFS做法)

Problem Description Benny has a spacious farm land to irrigate. The farm land is a rectangle, and is divided into a lot of samll squares. Water pipes are placed in these squares. Different square has a different type of pipe. There are 11 types of pi

并查集练习1

举头望明月,低头敲代码... 推荐学习地址:http://www.cnblogs.com/cyjb/p/UnionFindSets.html 简单: hdu1213 How Many Tables:新手必秒 1 #include<cstdio> 2 const int N=1001; 3 int f[N]; 4 void init(int n){ 5 for(int i=1;i<=n;++i) 6 f[i]=i; 7 } 8 int fin(int x){ 9 if(x!=f[x])f[

并查集知识学习

(转) 并查集的作用:并和查,即合并和查找,将一些集合合并,快速查找或判断某两个集合的关系,或某元素与集合的关系,或某两个元素的关系. 并查集的结构:并查集主要操作对象是森林,树的结构赋予它独特的能力,对整个集合操作转换为对根节点(或称该集合的代表元素)的操作,一个集合里的元素关系不一定确定,但相对于根节点的关系很明了,这也是为了查找方便. 并查集优化方法:按秩合并和路径压缩的配合使用,使得查找过程优化到极致.按秩合并,每次将深度小的树合并到深度大的树里面去,使得整棵树尽量矮:路径压缩,将当前节

并查集 专题总结

一.题目类型: 1.普通并查集: poj2513 Colored Sticks hdu1198 Farm Irrigation SCAU 1138 代码等式 Gym - 100676F Palindrome Codeforces Round #363 (Div. 2) D. Fix a Tree Codeforces Round #376 (Div. 2) C. Socks 2.种类并查集: HDU3038 How Many Answers Are Wrong POJ1182 食物链 POJ24

CodeForces 745C Hongcow Builds A Nation 并查集

题意: 给了你n个城市 m条边 k个政府 每个政府管辖的区域内不能和其他政府的区域有相连 即政府之间不存在路径 问你在维护这种关系的同时 最多再加多少条边 思路: 先找出来每个联通块 再找出来没有归属的孤立的点 把他们都放到最大的联通块里 然后每个联通块之间的点两两连边是n*(n-1)/2条边 最后算出来的ans-m就好了 (看别人的博客学了一个max_element 1 #include<bits/stdc++.h> 2 #define cl(a,b) memset(a,b,sizeof(a

并查集(个人模版)

并查集: 1 int find(int a) 2 { 3 int r=a; 4 while(f[r]!=r) 5 r=f[r]; 6 int i=a; 7 int j; 8 while(i!=r) 9 { 10 j=f[i]; 11 f[i]=r; 12 i=j; 13 } 14 return r; 15 } 16 int merge(int a,int b) 17 { 18 int A,B; 19 A=find(a); 20 B=find(b); 21 if(A!=B) 22 { 23 f[B