1.N皇后
#include<iostream>
using namespace std;
const int N = 12;
int vis[N][N], n, ans;
void dfs(int dep)
{
// 在这个搜索中dep表示行,i表示列
// 1 搜索出口
if(dep == n + 1)
{
ans++;
return;
}
// 2 继续搜索
for(int i = 1; i <= n; ++i)
{
// 2.1 排除非法情况
if(vis[dep][i])
continue;
// 2.2 改变状态
for(int _i = 1; _i <= n; ++_i)
vis[_i][i]++;
for(int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)
vis[_i][_j]++;
for(int _i = dep, _j = i; _i <= n && _j >= 1; ++_i, --_j)
vis[_i][_j]++;
for(int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)
vis[_i][_j]++;
for(int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)
vis[_i][_j]++;
// 2.3 下一层
dfs(dep + 1);
// 2.4 还原现场
for(int _i = 1; _i <= n; ++_i)
vis[_i][i]--;
for(int _i = dep, _j = i; _i >= 1 && _j >= 1; --_i, --_j)
vis[_i][_j]--;
for(int _i = dep, _j = i; _i <= n && _j >= 1; ++_i, --_j)
vis[_i][_j]--;
for(int _i = dep, _j = i; _i >= 1 && _j <= n; --_i, ++_j)
vis[_i][_j]--;
for(int _i = dep, _j = i; _i <= n && _j <= n; ++_i, ++_j)
vis[_i][_j]--;
}
}
int main()
{
cin >> n;
dfs(1);
cout << ans << "\n";
return 0;
}
2.最近公共祖先LCA查询
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 9;
int n;
vector<int> arr[N]; // 定义一个向量数组
int dep[N], fa[N][24];
void dfs(int u, int father) // 预处理
{
dep[u] = dep[father] + 1;
fa[u][0] = father;
for(int i = 1;i <= 20; ++ i)
{
fa[u][i] = fa[fa[u][i - 1]][i - 1];
}
for(const auto &x : arr[u])
if(x != father) // 只能往下探索
dfs(x, u);
}
int lca(int a, int b) // 求 a , b 的最近公共祖先
{
if(dep[a] < dep[b])swap(a, b);
// 先跳到同一层
for(int i = 20;i >= 0; -- i)
{
if(dep[fa[a][i]] >= dep[b])
a = fa[a][i];
// 如果 b 是 a 祖先,返回 b
if(a == b)return a;
}
// 再跳到lac的下一层
for(int i = 20;i >= 0; -- i)
{
if(fa[a][i] != fa[b][i])
{
a = fa[a][i];
b = fa[b][i];
}
}
return fa[a][0];
}
int main()
{
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> n;
for(int i = 1;i < n; ++ i)
{
int u, v; cin >> u >> v;
arr[u].push_back(v);
arr[v].push_back(u);
}
dfs(1, 0);
int q; cin >> q; // q 次查询
while(q -- )
{
int a, b; cin >> a >> b;
cout << lca(a, b) << '\n';
}
}