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.

  • 相关阅读:
    爬虫之JSON
    爬虫bs4案例
    爬虫bs4
    爬虫之Xpath案例
    爬虫之xpath
    监控 Kubernetes 集群应用
    手动部署k8s-prometheus
    ingress之tls和path使用
    ingress安装配置
    kube-dns和coreDNS的使用
  • 原文地址:https://www.cnblogs.com/MalcolmMeng/p/9692161.html
Copyright © 2011-2022 走看看