2019牛客多校E Androgynos——自补图&&构造

题目

给出一个 $n$,判断是否存在 $n$ 个顶点的自补图,如果存在,输出边和映射。

分析

一个无向图若同构于它的补图,则称该图为自补图

定理:一个自补图一定存在 $4k$ 或 $4k+1$ 个顶点.

证:

原图的边数+补图的边数=完全图的边数=n(n-1)/2

由于原图与补图同构,所以边数相等,

所以,原图的边数=n(n-1)/4,

边数肯定为整数,所以 4|n 或者 4|(n+1).

现在的问题是如何构造呢?

先考虑 $n=4k$,将其分成两半,

一半连接成完全图,一半为独立的点,

这样边数还不够,再将左上和右下一一相连,右上和左下一一相连。

很容易发现其补图变形一下就跟它一样,然后找一下对应关系。

2019牛客多校E Androgynos——自补图&&构造

#include<bits/stdc++.h>
using namespace std;

int n;

int  main()
{
    int T, kase=0;
    scanf("%d", &T);
    while(T--)
    {
        scanf("%d", &n);
        printf("Case #%d: ", ++kase);
        if(n % 4 == 0)
        {
            printf("Yes
");
            int k = n/4;
            for(int i = 1; i<= k;i++)
            {
                for(int j = 1; j <= 2*k;j++)
                {
                    if(j == i)   printf("0");
                    else   printf("1");
                }
                for(int j = 2*k+1;j <= 3*k;j++)  printf("0");
                for(int j = 3*k+1;j <= 4*k;j++)  printf("1");
                printf("
");
            }
            for(int i = k+1;i <= 2*k;i++)
            {
                for(int j = 1; j <= 2*k;j++)
                {
                    if(j == i)   printf("0");
                    else   printf("1");
                }
                for(int j = 2*k+1;j <= 3*k;j++)  printf("1");
                for(int j = 3*k+1;j <= 4*k;j++)  printf("0");
                printf("
");
            }
            for(int i = 2*k+1;i <= 3*k;i++)
            {
                for(int j = 1;j <= k;j++)  printf("0");
                for(int j = k+1;j <= 2*k;j++)  printf("1");
                for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                printf("
");
            }
            for(int i = 3*k+1;i <= 4*k;i++)
            {
                for(int j = 1;j <= k;j++)  printf("1");
                for(int j = k+1;j <= 2*k;j++)  printf("0");
                for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                printf("
");
            }
            for(int i = 4*k;i >= 3*k+1;i--)  printf("%d ", i);
            for(int i = 3*k;i >= 2*k+1;i--)  printf("%d ", i);
            for(int i = k;i >= 1;i--)  printf("%d ", i);
            for(int i = 2*k;i >= k+1;i--)  printf("%d%c", i, i == k+1? '
':' ');
        }
        else if(n % 4 == 1)
        {
            printf("Yes
");
            int k = n/4;
            for(int i = 1; i<= k;i++)
            {
                for(int j = 1; j <= 2*k;j++)
                {
                    if(j == i)   printf("0");
                    else   printf("1");
                }
                for(int j = 2*k+1;j <= 3*k;j++)  printf("0");
                for(int j = 3*k+1;j <= 4*k;j++)  printf("1");
                printf("1
");
            }
            for(int i = k+1;i <= 2*k;i++)
            {
                for(int j = 1; j <= 2*k;j++)
                {
                    if(j == i)   printf("0");
                    else   printf("1");
                }
                for(int j = 2*k+1;j <= 3*k;j++)  printf("1");
                for(int j = 3*k+1;j <= 4*k;j++)  printf("0");
                printf("1
");
            }
            for(int i = 2*k+1;i <= 3*k;i++)
            {
                for(int j = 1;j <= k;j++)  printf("0");
                for(int j = k+1;j <= 2*k;j++)  printf("1");
                for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                printf("0
");
            }
            for(int i = 3*k+1;i <= 4*k;i++)
            {
                for(int j = 1;j <= k;j++)  printf("1");
                for(int j = k+1;j <= 2*k;j++)  printf("0");
                for(int j = 2*k+1;j <= 4*k;j++)  printf("0");
                printf("0
");
            }
            for(int i = 1;i <= 2*k;i++)  printf("1");
            for(int i = 2*k+1;i <= 4*k+1;i++)  printf("0");
            printf("
");

            for(int i = 4*k;i >= 3*k+1;i--)  printf("%d ", i);
            for(int i = 3*k;i >= 2*k+1;i--)  printf("%d ", i);
            for(int i = k;i >= 1;i--)  printf("%d ", i);
            for(int i = 2*k;i >= k+1;i--)  printf("%d ", i);
            printf("%d
", 4*k+1);
        }
        else
        {
            printf("No
");
        }
    }
}