[CF1481D] AB Graph - 构造
Description
给定一个 n 个点的有向完全图,每条边被标上了一个字母 a 或者 b。要求找到一条长度为 m 的路径,使得路径上的边构成回文串。
Solution
如果存在 x,y 使得 (x,y)=(y,x),那么在这两个点上反复跳即可
如果 m 是奇数,那么随便找一条边反复跳即可
如果 m 是偶数,如果能找到 x,y,z,使得 (x,y)=(y,z),我们只要让 y 成为中间那个点,在三元环上循环走即可
剩下一种 m 是偶数,没有 (x,y)=(y,x),n=2 的情况,显然是无解的
#include <bits/stdc++.h>
using namespace std;
#define int long long
int check(const vector<int> &a, const vector<vector<int>> &g)
{
int n = a.size();
vector<int> b;
for (int i = 1; i < n; i++)
b.push_back(g[a[i - 1]][a[i]]);
for (int i = 0; i < n - 1; i++)
if (b[i] != b[n - i - 2])
return false;
return true;
}
void solve()
{
int n, m;
cin >> n >> m;
vector<vector<int>> g(n + 2, vector<int>(n + 2));
for (int i = 1; i <= n; i++)
{
string str;
cin >> str;
str = " " + str;
for (int j = 1; j <= n; j++)
if (str[j] == 'b')
g[i][j] = 1;
}
int eqi = 0, eqj = 0;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i != j && g[i][j] == g[j][i])
{
eqi = i;
eqj = j;
}
}
}
if (eqi > 0)
{
cout << "YES" << endl;
for (int i = 0; i <= m; i++)
{
if (i & 1)
cout << eqi << " ";
else
cout << eqj << " ";
}
}
else if (m & 1)
{
cout << "YES" << endl;
for (int i = 0; i <= m; i++)
cout << 1 + (i & 1) << " ";
}
else if (n <= 2)
{
cout << "NO";
}
else
{
cout << "YES" << endl;
vector<int> a[3];
for (int i = 0; i <= m; i++)
{
a[0].push_back((i + 0) % 3 + 1);
a[1].push_back((i + 1) % 3 + 1);
a[2].push_back((i + 2) % 3 + 1);
}
if (check(a[1], g))
a[0] = a[1];
if (check(a[2], g))
a[0] = a[2];
for (auto i : a[0])
cout << i << " ";
}
cout << endl;
}
signed main()
{
ios::sync_with_stdio(false);
int t;
cin >> t;
while (t--)
{
solve();
}
}