2019牛客多校第6场 Androgynos(构造)
题目大意
对于n个节点,构建出一幅图使得有,其补图为原图的一个映射使得其与原图同构
解题思路
https://math.stackexchange.com/questions/40745/constructing-self-complementary-graphs
只有 k = 4 n k=4n k=4n或 k = 4 n + 1 k=4n+1 k=4n+1时答案不为0.所有的答案都可以通过前面的答案不断+4个点得到。具体操作看上面的论坛。
AC代码
#include<bits/stdc++.h>
using namespace std;
int f[2005];
int g[2005][2005];
int main()
{
int t;
scanf("%d",&t);
for(int kace=1;kace<=t;kace++)
{
int n;scanf("%d",&n);
int ty=n%4;int id;
if(ty==2||ty==3)
{
printf("Case #%d: No\n",kace);
continue;
}
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
g[i][j]=0;
if(ty==1)
{
for(int i=ty;i<=n-4;i+=4)
{
for(int j=1;j<=i;j++)
{
g[i+2][j]=1;
g[j][i+2]=1;
g[i+3][j]=1;
g[j][i+3]=1;
}
g[i+1][i+2]=g[i+2][i+1]=1;
g[i+2][i+3]=g[i+3][i+2]=1;
g[i+3][i+4]=g[i+4][i+3]=1;
}
printf("Case #%d: Yes\n",kace);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d",g[i][j]);
}
puts("");
}
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=n/4;i++)
{
id=(i-1)*4+1;
swap(f[id+2],f[id+3]);
swap(f[id+1],f[id+2]);
swap(f[id+3],f[id+4]);
}
for(int i=1;i<=n;i++)
printf("%d%c",f[i],(i==n)?'\n':' ');
/*bool flag=true;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
if(g[f[i]][f[j]]!=(g[i][j]^1))
flag=false;
if(flag)
puts("Yes");*/
//变换顺序
}
else
{
ty=4;
g[1][2]=g[2][1]=g[2][3]=g[3][2]=g[3][4]=g[4][3]=1;
for(int i=ty;i<=n-4;i+=4)
{
for(int j=1;j<=i;j++)
{
g[i+2][j]=1;
g[j][i+2]=1;
g[i+3][j]=1;
g[j][i+3]=1;
}
g[i+1][i+2]=g[i+2][i+1]=1;
g[i+2][i+3]=g[i+3][i+2]=1;
g[i+3][i+4]=g[i+4][i+3]=1;
}
printf("Case #%d: Yes\n",kace);
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
printf("%d",g[i][j]);
}
puts("");
}
for(int i=1;i<=n;i++)
f[i]=i;
for(int i=1;i<=n/4;i++)
{
id=(i-1)*4;
swap(f[id+2],f[id+3]);
swap(f[id+1],f[id+2]);
swap(f[id+3],f[id+4]);
}
for(int i=1;i<=n;i++)
printf("%d%c",f[i],(i==n)?'\n':' ');
/*bool flag=true;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
if(i!=j)
if(g[f[i]][f[j]]!=(g[i][j]^1))
flag=false;
if(flag)
puts("Yes");*/
}
}
}