思路:首先使用DFS进行遍历,列举出所有亮灯的情况。然后使用并查集对每种情况进行判断,是否亮起的点在同一个连通块内。
#include<bits/stdc++.h>
#define N 8
//light表示亮的状态,map表示连通性 ,f[N]表示x的父亲
int light[N],map[N][N], f[N];
int ans=0;
//并查集
int find(int x) {
if(f[x] == x) {
return x;
} else {
//将x到根节点所经历的点的父亲都直接指向根节点,实现路径压缩
f[x] = find(f[x]);
return f[x];
}
}
//通过dfs遍历所有可能的情况
void dfs(int x) {
if(x == 8) {
for(int i=1; i<=7; i++) {
f[i] = i;
}
for(int i=1; i<=7; i++) {
for(int j=1; j<=7; j++) {
//当两个灯都亮而且相邻时
if(map[i][j]==1 && light[i]==1 && light[j] == 1){
//将i和j进行合并
int fx = find(i);
int fy = find(j);
if(fx!=fy) {
f[fx] = fy;
}
}
}
}
//当这些亮起的点在同一个连通块即表示为一种情况
int p = 0;
for(int i=1; i<=7; i++) {
if(light[i]==1 && f[i]==i) {
p++;
}
}
if(p == 1){
ans++;
}
return;
}
light[x] = 1;
dfs(x+1);
light[x] = 0;
dfs(x+1);
}
int main()
{
//初始化 ,列举相邻情况
map[1][2] = map[1][6] = 1;
map[2][1] = map[2][3] = map[2][7] = 1;
map[3][2] = map[3][4] = map[3][7] = 1;
map[4][3] = map[4][5] = 1;
map[5][4] = map[5][6] = map[5][7] = 1;
map[6][5] = map[6][1] = map[6][7] = 1;
map[7][2] = map[7][3] = map[7][5] = map[7][6] = 1;
dfs(1);
printf("%d", ans);
return 0;
}
最后得出答案:80