ACM乐园
Love Me,Love My Code!
posts - 53,  comments - 24,  trackbacks - 0
http://acm.hdu.edu.cn/showproblem.php?pid=1198

水源的数目就是合并后的根的数目,并查集的合并就是对m*n个点的合并,合并有两种方式,水平和垂直。
这道题初始化有点多,通过观察图形,记录图的上下左右四个方位是否连通,然后得出他们彼此之间是否连通。
#include <iostream>
#include 
<string>

using namespace std;

struct T 
{
    
bool right,left,down,up;
    T()
    
{
        right
=left=down=up=false;
    }

}
s[11];


int parent[2502];   //考虑这m*n个点能构成多少个连通分量
bool link1[11][11]; //是否水平相连
bool link2[11][11]; //是否垂直相连
char map[51][51];


void init() //初始化这11张图片是否相连,包括水平、垂直两种方式
{
    
int i,j;
    s[
0].left=s[2].left=s[5].left=s[6].left=s[7].left=s[8].left=s[10].left=true;
    s[
1].right=s[3].right=s[5].right=s[6].right=s[8].right=s[9].right=s[10].right=true;
    s[
0].up=s[1].up=s[4].up=s[6].up=s[7].up=s[9].up=s[10].up=true;
    s[
2].down=s[3].down=s[4].down=s[7].down=s[8].down=s[9].down=s[10].down=true;
    
for(i=0;i<11;i++)
        
for(j=0;j<11;j++)
        
{
            link1[i][j]
=s[i].right && s[j].left;
            link2[i][j]
=s[i].down && s[j].up;
        }

}


int UFfind(int i)
{
    
int j,temp;
    
for(j=i;parent[i]>=0;i=parent[i]);
    
while(j!=i)
    
{
        temp
=parent[j];
        parent[j]
=i;
        j
=temp;
    }

    
return i;
}


void UFunion(int i,int j)
{
    
int temp;
    i
=UFfind(i);
    j
=UFfind(j);
    
if(i==j)
        
return;
    temp
=parent[i]+parent[j];
    
if(parent[i]<=parent[j])
    
{
        parent[i]
=temp;
        parent[j]
=i;
    }

    
else
    
{
        parent[j]
=temp;
        parent[i]
=j;
    }

}


int main()
{
    
int i,j,m,n,pi,pj,res;
    init();
    
while(cin>>m>>n,(m+n)!=-2)
    
{
        memset(parent,
-1,sizeof(parent));
        res
=0;
        
for(i=0;i<m;i++)
            cin
>>map[i];
        
for(i=0;i<m;i++)
            
for(j=0;j<n;j++)
            
{
                
if(j<n-1 && link1[map[i][j]-'A'][map[i][j+1]-'A'])
                
{
                    pi
=i*n+j;
                    pj
=i*n+j+1;
                    UFunion(pi,pj);
                }

                
if(i<m-1 && link2[map[i][j]-'A'][map[i+1][j]-'A'])
                
{
                    pi
=i*n+j;
                    pj
=(i+1)*n+j;
                    UFunion(pi,pj);
                }

            }

        
for(i=0;i<m;i++)       //搜索根的数目
            for(j=0;j<n;j++)
                
if(parent[i*n+j]<0)
                    res
++;
        cout
<<res<<endl;
    }

    
return 0;
}



posted on 2011-09-15 12:38 大大木马 阅读(315) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理



<2011年9月>
28293031123
45678910
11121314151617
18192021222324
2526272829301
2345678

常用链接

留言簿(1)

随笔档案(53)

文章档案(2)

搜索

  •  

积分与排名

  • 积分 - 63780
  • 排名 - 351

最新评论

阅读排行榜

评论排行榜