zoukankan      html  css  js  c++  java
  • 【并查集】一种迷宫生成算法

    并查集的应用之一。

    主要思路是:

    将所有墙加入一个vector
    while vector非空:
    	在vector中随机选一个墙
    	墙的两边是否联通?
    		否: 联通墙的两边(打破墙)0
    	删除本墙
    

    代码:

    #include<bits/stdc++.h>
    #include<conio.h>
    using namespace std;
    int fa[10000],dx[2]={0,1},dy[2]={1,0},n=15,mp[21][21][21][21];
    //n可修改 为迷宫大小 同时为防止溢出请修改fa和mp大小
    int WtoN(int a,int b){
    	return (a-1)*n+b;
    }//将墙的(1,1)转为第1个的序号
    int found(int f){
    	if(fa[f]==f)return f;
    	else return fa[f]=found(fa[f]);
    }//并查集
    struct wall{
    	int fx,fy,sx,sy;
    	void merge(){
    		fa[found(WtoN(fx,fy))]=found(WtoN(sx,sy));
    	}//让并查集好看一些 在struct里面写了一个
    	bool check(){
    		return found(WtoN(fx,fy))==found(WtoN(sx,sy));
    	}
    };
    void print(){
    	for(int i=1;i<=3*n+1;i++)cout<<"#";
    	cout<<endl;
    	for(int i=1;i<=n;i++){
    		cout<<"#";
    		for(int j=1;j<=n;j++)cout<<"  "<<(((j!=n)&&(mp[i][j][i][j+1]))?" ":"#");
    		cout<<endl;
    		for(int j=1;j<=n;j++)cout<<"#"<<(((i!=n)&&(mp[i][j][i+1][j]))?"  ":"##");
    		cout<<"#"<<endl;
    	}
    }//输出 不多讲 mp[][][][]==1代表当前墙被打破了
    int main(){
    	srand((unsigned int)time(NULL));
    	for(int i=1;i<=n*n;i++)fa[i]=i;
    	vector<wall>vc;
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			for(int d=0;d<2;d++){
    				int rx=i+dx[d],ry=j+dy[d];
    				if(rx>0&&ry>0&&rx<=n&&ry<=n)vc.push_back((wall){i,j,rx,ry});
    			}
    		}
    	}//初始化墙列表
    	while(!vc.empty()){
    		int v=rand()%vc.size();//选择一面墙
    		if(!vc[v].check())vc[v].merge(),mp[vc[v].fx][vc[v].fy][vc[v].sx][vc[v].sy]=1;//打破墙
    		vc.erase(vc.begin()+v);//删除
    	}
    	print();
    	system("pause");
    }
    
  • 相关阅读:
    Step By Step(Lua-C API简介)
    Step By Step(Lua系统库)
    复制控制( 下 ) --- 自定义析构函数
    复制控制( 中 ) --- 重载赋值运算符
    复制控制( 上 ) --- 自定义复制函数
    泛型算法结构
    流迭代器 + 算法灵活控制IO流
    一个文本查询程序的实现
    multimap容器和multiset容器中的find操作
    实用的关联容器
  • 原文地址:https://www.cnblogs.com/haraki/p/oi_maze_bcj.html
Copyright © 2011-2022 走看看