私は、壁を取り除いて迷路を作るアルゴリズムを学びました。
int friendGroups[N];
// initially, all numbers are in a "forever alone" group.
for(i = 0; i < N; i++) {
friendGroups[i] = i;
}
int findFriendGroup(int p) {
int g = friendGroups[p];
if (g != p) {
g = friendGroups[p] = findFriendGroup(g);
}
return g;
}
void addFriendship(int i, int j) {
friendGroup[findFriendGroup(i)] = findFriendGroup(j);
}
int areFriends(int i, int j) {
return (findFriendGroup(i) == findFriendGroup(j));
}
findFriendGroup()
潜在的に非効率的に見えますが、各呼び出しは漸近的に O(A^(-1)(N)) のコストがかかります。ここで、A^(-1) は逆アッカーマン関数であり、O(1) に非常に近いため、心配する必要はありません。
int singleFriendGroup() {
int g = findFriendGroup(0);
int i;
for(i = 1; i < N; i++) {
if (findFriendGroup(i) != g) {
return 0;
}
}
return 1;
}
各人は、他の人または自分自身を「指し示し」ます。各フレンド グループには、自分自身を指し示すプライマリ メンバーがいます ( friendGroups[i] == i
)。 findFriendGroup()
ポイントのチェーンをたどってグループの主要メンバーを見つけ、その途中でチェーン内の各人を直接主要メンバーに向けさせます。2 つのグループを統合するには ( addFriendship()
)、1 つのグループのプライマリ メンバが別のグループのプライマリ メンバを指すようにします。