一開始假設所有牆都在,也就是圖的每個點都不連通。如果當前不滿足“任意兩個格子間都有唯一路徑”,那麼就隨機選擇一堵牆,要求牆兩端的格子不連通,即它們對應的兩個頂點在兩個不同的連通分量。把這堵牆拆掉,即在後牆兩端的格子對應的頂點間建立一條邊。重複作下去,直到所有的點都在同一個連通分量裡面。
會發現這就是隨機合併點的Kruskal演算法,需要用到並查集
範例生成圖:
#########################
# # # # #
### # # # ### ####### ###
# # # # # # #
######### ### # # ##### #
# # # # # #
### ### # # # ### ### ###
# # # # # #
### # ##### ### ##### ###
# # # # # # #
####### # ### # ####### #
# # # # # # # #
# ### ### ### # ##### # #
# # # # # # # # # #
# # ### # ### ### # # # #
# # # # # #
# # ### ######### # #####
# # # # # # # #
####### # # # # ### ### #
# # # # #
# # ##### ######### # ###
# # # # #
### # # ### # ####### ###
# # # # # # #
#########################
code(n,m必須是奇數):
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include<bits/stdc++.h> | |
using namespace std; | |
struct P{ | |
P(int q,int w,int e,int r):a(q),b(w),x(e),y(r){} | |
int a,b; | |
int x,y; | |
}; | |
char s[105][105]; | |
int id[105][105],cnt; | |
int st[10005]; | |
vector<P>p; | |
inline int find(int x){ | |
return st[x]==x?x:st[x]=find(st[x]); | |
} | |
inline void print(int n,int m){ | |
for(int i=0;i<n;++i){ | |
for(int j=0;j<m;++j){ | |
if(s[i][j]=='#')printf("#"); | |
else printf(" "); | |
} | |
puts(""); | |
} | |
} | |
int main(){ | |
int n=25,m=25; | |
for(int i=0;i<n;++i){ | |
for(int j=0;j<m;++j){ | |
s[i][j]='#'; | |
} | |
} | |
for(int i=1;i<n;i+=2){ | |
for(int j=1;j<m;j+=2){ | |
id[i][j]=++cnt; | |
s[i][j]=' '; | |
} | |
} | |
for(int i=1;i<n-1;++i){ | |
for(int j=1;j<m-1;++j){ | |
if(s[i][j]=='#'){ | |
if(s[i][j-1]!='#'&&s[i][j+1]!='#'){ | |
p.push_back(P(id[i][j-1],id[i][j+1],i,j)); | |
}else if(s[i-1][j]!='#'&&s[i+1][j]!='#'){ | |
p.push_back(P(id[i-1][j],id[i+1][j],i,j)); | |
} | |
} | |
} | |
} | |
for(int i=1;i<=cnt;++i)st[i]=i; | |
srand(time(0)); | |
random_shuffle(p.begin(),p.end()); | |
for(int i=0;i<(int)p.size();++i){ | |
if(find(p[i].a)!=find(p[i].b)){ | |
st[find(p[i].a)]=find(p[i].b); | |
s[p[i].x][p[i].y]=' '; | |
} | |
} | |
print(n,m); | |
return 0; | |
} |
沒有留言:
張貼留言