zoukankan      html  css  js  c++  java
  • codeforces990D

    链接http://codeforces.com/problemset/problem/990/D

    构造类型的题目。

    这道题目要求构造一个无向图,使得原图和补图的极大连通子图符合要求的数量。

    这种构造类型的题目,都要去寻找规律和特点(对我来说很难)。看了题解,也算是学习了新知识了。

    官方的题解:链接

    关键点就是 如果原图或补图有一个图的极大连通子图的数目大于1,则另一个图的极大连通子图的数目一定等于1。证明如下:

    假设原图的极大连通子图的数目大于1,u,v为图中的任意一对顶点。

    如果u,v位于不同的极大连通子图,那么u,v在补图中是连通的。

    如果u,v位于同一个极大连通子图,那么u,v可以与另一个极大连通子图中的同一个点相连,所以也是连通的。

    设原图极大连通子图数目为a,补图为b

    特殊情况为a=1,b=1。n=2或3时无解,其他情况有解

    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<string>
    #include<vector>
    #define DEBUG(x) cout<<#x<<" = "<<x<<endl
    using namespace std;
    const int MAXN=1e3+10;
    int n,a,b;
    int mat[MAXN][MAXN];
    int main()
    {
    //    freopen("in.txt","r",stdin);
        scanf("%d%d%d",&n,&a,&b);
        if((n==2||n==3)&&a==1&&b==1)printf("NO
    ");
        else if(a!=1&&b!=1)printf("NO
    ");
        else {
            printf("YES
    ");
            int cnt=0;
            if(a>1){
                int cur=1;
                while(cur<=n-a){//使用首尾相连的方法构图
                    mat[cur-1][cur]=mat[cur][cur-1]=1;
                    cur++;
                }
            }
            else if(b>1){
                int cur=1;
                while(cur<=n-b){
                    mat[cur-1][cur]=mat[cur][cur-1]=1;
                    cur++;
                }
                for(int i=0;i<n ;i++ ){
                    for(int j=0;j<n ;j++ ){
                        if(i!=j)mat[i][j]=1-mat[i][j];
                    }
                }
            }
            else {
                int cur=1;
                while(cur<n){
                    mat[cur-1][cur]=1;
                    mat[cur][cur-1]=1;
                    cur++;
                }
            }
            for(int i=0;i<n ;i++ ){
                for(int j=0;j<n ;j++ ){
                    printf("%d",mat[i][j]);
                }
                printf("
    ");
            }
        }
    }

    Let's prove that if a>1a>1, then b=1b=1. Let GG be the original graph, and HH — the complement of the graph GG. Let's look at each pair of vertices (u,v)(u,v). If uu and vv belong to different components of the graph GG, then there is an edge between them in the graph HH. Otherwise, uu and vv belong to the same component of the graph GG, but since GG has more than one component, there is vertex xx in other component of GG, and there are edges {u,x}{u,x} and {v,x}{v,x} in HH. That's why, there is a connected path for any pair of vertices (u,v)(u,v), and the graph HH is connected. Similarly, the case b>1b>1 is proved.

    So, if min(a,b)>1min(a,b)>1, then the answer is "NO". Otherwise, min(a,b)=1min(a,b)=1. Consider the case where b=1b=1 (if b>ab>a, we can swap aa and bb, and output complement of the constructed graph). To have aa components in the graph GG, it is enough to connect the vertex 11 with the vertex 22, the vertex 22 with the vertex 33, the vertex nan−a with the vertex na+1n−a+1.

    A particular cases are the tests n=2,a=1,b=1n=2,a=1,b=1 and n=3,a=1,b=1n=3,a=1,b=1. There is no suitable graph for them.

  • 相关阅读:
    如何:使用向导来处理项目模板 【转载】
    .NET : 如何在生成XML文档时绑定样式表
    如何在生产环境部署K2的流程
    SQL Server 数据库文档生成工具开源项目【合作邀请】
    新的纪元
    SharePoint : 谁说WSS不支持审核
    C++ : 类型的别名和对象的别名
    C++: 引用和地址运算符
    Infopath : 如何通过代码复制格式文本框的值
    正确地使用投影仪和移动硬盘
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/9692161.html
Copyright © 2011-2022 走看看