2019牛客暑期多校训练营(第六场)E 构造、原图是补图的同构图

https://ac.nowcoder.com/acm/contest/886#question

题意  问是否存在某个n个点的无向图G是其补图H的同构图,若存在输出G的邻接矩阵以及H关于G的映射。

解析  构造题,答案不唯一。原图与补图边数要一样,所以当n=4*k+2和4*k+3时无解

当n=4*k 时 将点分成4部分P1,P2,P3,P4  前两部分P1P2所有的点两两连边组成团,P3P1部分与部分之间两两连边,P4P2部分与部分之间两两连边

它的补图 是 P3P4组成团,P4P1之间连边,P3P2之间连边,与原图是同构的。

块之间映射关系,原图 P1P2P3P4 补图P3P4P2P1或其他方案。

当n=4*k+1时 剩下一个点随便和两个块连就好了。

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn = 2e3+10;
int g[maxn][maxn];
int main()
{
    int t,n,kase=1;
    cin>>t;
    while(t--){
        cin>>n;
        memset(g,0,sizeof(g));
        printf("Case #%d: ",kase++);
        if(n%4==2||n%4==3){
            cout<<"No"<<endl;
            continue;
        }
        else {
            cout<<"Yes"<<endl;
            int block=n/4;
            for(int i=1;i<=block;i++){
                for(int j=block+1;j<=2*block;j++)
                    g[i][j]=g[j][i]=1;
                for(int j=2*block+1;j<=3*block;j++)
                    g[i][j]=g[j][i]=1;
                for(int j=i+1;j<=block;j++)
                    g[i][j]=g[j][i]=1;
            }
            for(int i=block+1;i<=2*block;i++){
                for(int j=3*block+1;j<=4*block;j++)
                    g[i][j]=g[j][i]=1;
                for(int j=i+1;j<=2*block;j++)
                    g[i][j]=g[j][i]=1;
            }
            if(n%4==1){
                for(int i=1;i<=2*block;i++)
                    g[i][n]=g[n][i]=1;
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++)
                        printf("%d",g[i][j]);
                    printf("
");
                }
                for(int i=2*block+1;i<=4*block;i++)
                    printf("%d ",i);
                for(int i=2*block;i>=1;i--)
                    printf("%d ",i);
                printf("%d
",n);
            }
            else{
                for(int i=1;i<=n;i++){
                    for(int j=1;j<=n;j++)
                        printf("%d",g[i][j]);
                    printf("
");
                }
                for(int i=2*block+1;i<=4*block;i++)
                    printf("%d ",i);
                for(int i=2*block;i>=1;i--)
                    printf("%d%c",i,i==1?'
':' ');
            }
        }

    }
}
原文地址:https://www.cnblogs.com/stranger-/p/11298938.html