ZJU2412 Farm Irrigation - 水管连通

来源:互联网 发布:工业设计用的软件 编辑:程序博客网 时间:2024/04/28 22:23

题目描述:

有A-K共11种不同的水管,每个水管的连通方向不同。给出一个M×N的田地水管图,求出最少需要多少个出水口可以灌溉全部田地。 原题 ZJU2412 

分析:

粗略一看,此题可以用搜索算法来做。即寻找一共有多少个连通分量。

求图有多少连通分量,一个很高效的方法是用并查集。此题也可以用并查集来解决。

对于地图中每个格子,判断它的水管能否与其上面和左面的格子连通。若能,则并在一起。

最后统计并查集中有多少连通分支即可。

代码,0.00s

/*
ZJU2412 Farm Irrigation
*/

#include <stdio.h>
#define N 51
#define id(i,j) (i*m+j+1)

int dir[][2]={{-1,0},{0,-1}}; //up down
int link[][4]={  {1,0,1,0},{1,1,0,0}  //A B
                ,{0,0,1,1},{0,1,0,1}  //C D
                ,{1,0,0,1},{0,1,1,0}  //E F
                ,{1,1,1,0},{1,0,1,1}  //G H
                ,{0,1,1,1},{1,1,0,1}  //I J
                ,{1,1,1,1}};          //K

int f[N*N],m,n;
char map[N][N],ch;
int x,y,u,v,p,q,t;

int connect(int u,int v,int e){
    if(!e){ //up down
        if(link[u][0]&&link[v][3]) return 1;
        else return 0;
    }
    else{  //left right
        if(link[u][2]&&link[v][1]) return 1;
        else return 0;
    }
}

int root(int p){
    q=p;
    while(f[q]) q=f[q];
    while(f[p]){
        t=f[p];
        f[p]=q;
        p=t;
    }
    return q;
}

void work(int i,int j,int e){
    x=i+dir[e][0];
    y=j+dir[e][1];
    u=map[i][j];
    v=map[x][y];
    if(connect(u,v,e)){
        p=root(id(i,j));
        q=root(id(x,y));
        if(p!=q) f[p]=q;
    }
}

int main()
{
    int i,j,k,ans;
   
    while(scanf("%d%d",&n,&m),m!=-1||n!=-1)
    {
        //input
        getchar();
        for(i=0;i<n;i++){
            for(j=0;j<m;j++){
                scanf("%c",&ch);
                map[i][j]=ch-'A';
            }
            getchar();
        }
       
        //init
        for(i=0;i<=n*m;i++) f[i]=0;
       
        //work
        for(i=0;i<n;i++){
            for(j=0;j<m;j++){
                if(i) work(i,j,0);  //up
                if(j) work(i,j,1);  //left
            }
        }
       
        //count
        ans=0;
        for(i=0;i<n;i++)
            for(j=0;j<m;j++){
                k=id(i,j);
                if(root(k)==k) ans++;
            }
       
        //output
        printf("%d/n",ans);
    }
   
    return 0;
}