牛客多校第六场 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);
        }
    }
}

猜你喜欢

转载自www.cnblogs.com/isakovsky/p/11296632.html