码迷,mamicode.com
首页 > 其他好文 > 详细

L - Farm Irrigation (并查集

时间:2019-04-06 00:18:41      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:注意   mes   break   cout   int   ini   find   void   pre   

给你一个管道地图,求联通块个数

 

很简单的并查集,简单预处理输入一下

 

但zoj能过,hdu就是莫名其妙的wa

后来发现是我地图的表示时边界的处理有问题

 

例如

ABD

KJH

KNG

我把这个矩阵读取成一行:ABDKJHKNG

对于第i个元素 上下左右就表示为 ut=i - n ,lt=i -1 ,rt=i+1 ,dt=i+n;

判断边界:  ut>0   i%n !=1   i%n !=0  dt<=m*n

这样平常没什么问题,所以zoj能过

但是。。。 当矩阵宽度为1时,左右边界就会合并,这时判断 左边界 i%n !=1 就会出错,因为此时“余1” 就是 余0

所以要特判一下1.。。。

以后这种情况要特别注意(不过再碰到题我可能就不这样表示上下左右了)

#include <cstdio>
#include <iostream>
#include <string>
#include <cstring>
#include <algorithm>

using namespace std;

int pre[500000];
int node[500000];
const int u[50 ]={1,1,0,0,1,0,1,1,0,1,1};
const int l [50 ]={1,0,1,0,0,1,1,1,1,0,1};
const int r [50 ]={0,1,0,1,0,1,1,0,1,1,1};
const int d[50 ]={0,0,1,1,1,0,0,1,1,1,1};

void init( int n){
     for( int i=0 ;i<=n;i++)
        pre[i] = i;
}

int find( int x){

     int r= x;
     while( pre[x] != x){
        x= pre[x];
     }
     int t;
     while( r!=x){
        t = pre[r];
        pre[r] = x;
        r = t;
     }
     return x;
}

void add( int a ,int b){
   // cout<<a <<‘ ‘<<b<<endl;
    int x=find(a);
    int y=find(b);
    if( x!=y) pre[x] =y;
    return ;
}

int main( ){
     int m ,n;
     while( cin>>m>>n){
            if( m<0 || n<0) break;
         int an = m*n;
         init( an);
         string op;
         int cnt = 1;
         for( int i=1 ;i<=m ;i++){
            cin>> op;
            for( int j=0 ; j<n ;j++)
                node[cnt++] =(int)(op[j]-A);
         }

         for( int i=1 ;i<=an ;i++){
             int t=node[i];
             int ut=i - n ,lt=i -1 ,rt=i+1 ,dt=i+n;
             if( u[ t] && ut>0 && d[ node[ut] ])add(i ,ut);
             if( l[ t] && i%n !=1 && n !=1 && r[ node[lt] ])add(i ,lt); //就是这一行
             if( r[ t] && i%n !=0  && n !=1&& l[ node[rt] ])add(i ,rt);
             if( d[ t] && dt<=an && u[ node[dt] ])add(i ,dt);
         }
         int ans=0;
         for( int i=1 ; i<=an ;i++){
            if( pre[i] == i)ans++;
          //  cout<<i<<‘ ‘<<pre[i]<<endl;
         }
         printf("%d\n" ,ans);
     }
     return 0;
}

 

L - Farm Irrigation (并查集

标签:注意   mes   break   cout   int   ini   find   void   pre   

原文地址:https://www.cnblogs.com/-ifrush/p/10660433.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!