链接: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;
}