牛客多校第六场 E Androgynos 自补图
题意:
给定点数,构造自补图,要求输出邻接矩阵,和原图与补图的同构映射。
题解:
只有点数为4k和4k+1的情况才能构造自补图,因为只有这些情况下边数才为偶数。
一种构造方式是,邻接矩阵和同构映射增量构造,每次加四个边xyzw,x和w连接原来的所有边,yz不连,同构映射是交换xy,zw
参考:www.matrix67.com/blog/archives/6221
#include<bits/stdc++.h> using namespace std; typedef long long LL; const int M = 2e3 + 5; const LL mod = 998244353; const LL lINF = 0x3f3f3f3f3f3f3f3f; bool mp[M][M]; int t; int n; int a[M]; int main() { scanf("%d", &t); for (int cnt = 1; cnt <= t; cnt++) { scanf("%d", &n); if (n % 4 == 0) { printf("Case #%d: Yes\n", cnt); memset(mp, 0, sizeof mp); mp[2][1] = mp[1][2] = 1; mp[2][3] = mp[3][2] = 1; mp[3][4] = mp[4][3] = 1; a[1] = 2; a[2] = 4; a[3] = 1; a[4] = 3; for (int i = 5; i <= n; i += 4) { mp[i][i + 1] = mp[i + 1][i] = 1; mp[i + 1][i + 2] = mp[i + 2][i + 1] = 1; mp[i + 2][i + 3] = mp[i + 3][i + 2] = 1; for (int j = 0; j < 4; j+=3) { for (int k = 1; k < i; k++) { mp[i + j][k] = mp[k][i + j] = 1; } } a[i] = i + 1; a[i + 1] = i; a[i + 2] = i + 3; a[i + 3] = i + 2; swap(a[i+1], a[i + 2]); } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%d", mp[i][j]); } puts(""); } for (int i = 1; i < n; i++) { printf("%d ", a[i]); } printf("%d\n", a[n]); } else if (n % 4 == 1) { printf("Case #%d: Yes\n", cnt); memset(mp, 0, sizeof mp); a[1] = 1; for (int i = 2; i <= n; i += 4) { mp[i][i + 1] = mp[i + 1][i] = 1; mp[i + 1][i + 2] = mp[i + 2][i + 1] = 1; mp[i + 2][i + 3] = mp[i + 3][i + 2] = 1; for (int j = 0; j < 4; j+=3) { for (int k = 1; k < i; k++) { mp[i + j][k] = mp[k][i + j] = 1; } } a[i] = i + 1; a[i + 1] = i; a[i + 2] = i + 3; a[i + 3] = i + 2; swap(a[i+1], a[i + 2]); } for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) { printf("%d", mp[i][j]); } puts(""); } for (int i = 1; i < n; i++) { printf("%d ", a[i]); } printf("%d\n", a[n]); } else { printf("Case #%d: No\n", cnt); } } }