2019牛客暑期多校训练营(第六场)E——Androgynos(构造)

链接:https://ac.nowcoder.com/acm/contest/886/E
来源:牛客网
 

时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
Special Judge, 64bit IO Format: %lld

题目描述

In graph theory, an isomorphism of graphs G and H is a bijection between the vertex sets of G and H. The complement of a graph G is a graph H on the same vertices such that two distinct vertices of H are adjacent if and only if they are not adjacent in G.

Give a positive integer n, check whether there exists a simple undirected graph G having n vertices, which is isomorphic to its complement graph H. If the graphs G and H exist, report them with any possible isomorphism.

输入描述:

There are multiple test cases. The first line contains an integer T (1≤T≤51 \leq T \leq 51≤T≤5), indicating the number of test cases. Test cases are given in the following.

Each test case consists of only one line, containing an integer n (1≤n≤20001 \leq n \leq 20001≤n≤2000).

输出描述:

 

For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1, and y (y∈{Yes,No}y \in \lbrace \text{Yes}, \text{No} \rbracey∈{Yes,No}) denotes whether or not the graphs exist in this test case.

If the graphs exist, then output (n + 1) extra lines.

The first n lines represent the graph G, where each line contains a binary string of length n. In the i-th line, the j-th character Gi,jG_{i, j}Gi,j​ is '1' when the i-th vertex and the j-th one are adjacent, or otherwise, in case they are not adjacent, Gi,jG_{i, j}Gi,j​ is '0'. Note that Gi,iG_{i, i}Gi,i​ must be '0' and Gi,jG_{i, j}Gi,j​ must be the same as Gj,iG_{j, i}Gj,i​.

The last line contains n space-separated integers f1f_1f1​, f2f_2f2​, …\ldots…, fnf_nfn​, representing an isomorphism of graphs G and H in which the i-th vertex in the graph G is mapped to the fif_ifi​-th vertex in the complement graph H. Note that every two consecutive integers in one line should be separated by a single space, please do not add any tailing space in your output\text{please do not add any tailing space in your output}please do not add any tailing space in your output. 

示例1

输入

复制

4
1
2
3
4

输出

复制

Case #1: Yes
0
1
Case #2: No
Case #3: No
Case #4: Yes
0100
1010
0101
0010
2 4 1 3

题意:求有n个顶点(顶点为1-n)的图与它的补图同构,构造出这个图,并输出在补图中对应的点;

题解:

上代码(模拟图片最上面的图构造就好了,注意是双向边,对应点也是根据图输出):

#include <bits/stdc++.h>
using namespace std;
int a[2500][2500];
void fuck1(int n){
    for (int i = 1; i <= n/2;i++){
        for (int j = i+1; j <= n/2;j++){
            a[i][j]=1;
            a[j][i]=1;
        }
    }
    for (int i = 1; i <= n/4;i++){
        for (int j = 1; j <= n/4;j++){
            a[i][n/2+j]=1;
            a[n/2+j][i]=1;
        }
    }
    for (int i = n/4+1; i <= n/2;i++){
        for (int j = n/4+1; j <= n/2;j++){
            a[i][n/2+j]=1;
            a[n/2+j][i]=1;
        }
    }
}
void fuck2(int n){
    for (int i = 1; i <= n/2;i++){
        a[n][i]=1;
        a[i][n]=1;
    }
    n--;
    for (int i = 1; i <= n/2;i++){
        for (int j = i+1; j <= n/2;j++){
            a[i][j]=1;
            a[j][i]=1;
        }
    }
    for (int i = 1; i <= n/4;i++){
        for (int j = 1; j <= n/4;j++){
            a[i][n/2+j]=1;
            a[n/2+j][i]=1;
        }
    }
    for (int i = n/4+1; i <= n/2;i++){
        for (int j = n/4+1; j <= n/2;j++){
            a[i][n/2+j]=1;
            a[n/2+j][i]=1;
        }
    }
}
void print(int n){
    for (int i = 1; i <= n;i++){
        for (int j = 1; j <= n;j++){
            printf("%d",a[i][j]);
        }
        puts("");
    }
    if(n==1){
        printf("1\n");
        return;
    }
    int x=n;
    if(n&1) n--;
    for (int i = n; i >= n/2+1;i--){
        if(i==n) printf("%d",i);
        else printf(" %d",i);
    }
    for (int i = 1; i <= n/2;i++){
        printf(" %d",i);
    }
    if(x&1) printf(" %d\n",x);
    else puts("");
}
void init(int n){
    for (int i = 1; i <= n;i++){
        for (int j = 1; j <= n;j++){
            a[i][j]=0;
        }
    }
}
int main(){
    int cas=1;
    int t;
    scanf("%d",&t);
    while(t--){
        int n;
        scanf("%d",&n);
        init(n);
        printf("Case #%d: ",cas++);
        if(n%4==2||n%4==3){
            puts("No");
            continue;
        }
        puts("Yes");
        if(n%4==0){
            fuck1(n);
            print(n);
        }
        else{
            fuck2(n);
            print(n);
        }
    }
    return 0;
}
发布了195 篇原创文章 · 获赞 27 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/lgz0921/article/details/98455515
今日推荐