zoukankan      html  css  js  c++  java
  • Codeforces 990D Graph And Its Complement 【构造】【性质】

    第一次做constructive algorithm的题,要我们构造出来一个图使得它的连通分量有a个,补图的连通分量有b个。

    关键在于想到一个性质是图和补图至少有一个图是连通图。(这个性质的想到可以通过看样例2,然后多画点图就想出来了)那我们就知道a和b肯定有一个是1,那我们构造另一个不是1的就可以了(因为一个联通分量个数不是1的补图的联通分量个数一定是1)。这样问题就变成了怎么构造一个图使得他有x个联通分量,这个就比较简单了,这个图有n个点,那就前x-1个点一个点就是一个连通分量,剩下的点是一个联通分量。

    注意到n>4的话a和b都能为1,但n=2,3的情况a和b只能一个为1,n=1可以都为1。所以要特判

    n>4且a和b都为1的情况,构造一条链就行了

     1 #include<iostream>
     2 using namespace std;
     3 
     4 int n,a,b,count=1;
     5 int edge[1005][1005];
     6 
     7 int main(){
     8     cin>>n>>a>>b;
     9     if(a!=1 && b!=1){//补图和原图至少一个联通 
    10         cout<<"NO"; 
    11         return 0;
    12     }
    13 
    14     if(a!=1){//构造一个有a个联通分量的图
    15         a--;
    16         while(a--){
    17             for(int i=1;i<=n;i++) edge[count][i]=edge[i][count]=0;//这个点是一个联通分量
    18             count++; 
    19         }
    20         for(int i=count+1;i<=n;i++) edge[count][i]=edge[i][count]=1;//这个点跟剩下的点组成一个无环连通分量
    21         cout<<"YES"<<endl;
    22         for(int i=1;i<=n;i++){
    23             for(int j=1;j<=n;j++) cout<<edge[i][j];
    24             cout<<endl;
    25         }
    26         return 0;
    27     }
    28     if(b!=1){//构造一个有b个联通分量的图
    29         b--;
    30         while(b--){
    31             for(int i=1;i<=n;i++) edge[count][i]=edge[i][count]=0;//这个点是一个联通分量
    32             count++; 
    33         }
    34         for(int i=count+1;i<=n;i++) edge[count][i]=edge[i][count]=1;//这个点跟剩下的点组成一个无环连通分量
    35         cout<<"YES"<<endl;
    36         for(int i=1;i<=n;i++){
    37             for(int j=1;j<=n;j++) {
    38                 if( i==j ) cout<<0;
    39                 else cout<<!edge[i][j];
    40             }
    41             cout<<endl;
    42         }
    43         return 0;
    44     }
    45     
    46     if(a==1 && b==1 && n>=4){
    47         int connect=1;
    48         for(int i=2;i<=n;i++){
    49             edge[connect][i]=edge[i][connect]=1;
    50             connect=i;
    51         }
    52         cout<<"YES"<<endl;
    53         for(int i=1;i<=n;i++){
    54             for(int j=1;j<=n;j++) cout<<edge[i][j];
    55             cout<<endl;
    56         }    
    57         return 0;
    58     }
    59     
    60     if(a==1 && b==1){
    61         if(n==1) cout<<"YES"<<endl<<0;
    62         else cout<<"NO";
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    Flexigrid在IE下不显示数据的处理
    [置顶] ios 网页中图片点击放大效果demo
    WPF仿360卫士9.0界面设计
    Android调用相机并将照片存储到sd卡上
    Android 将文件保存到SD卡,从卡中取文件,及删除文件
    java 正则表达式学习
    linux下的块设备驱动(一)
    已知用经纬度表示的两点,求两点之间的直线距离
    IndiaHacks 2016
    IndiaHacks 2016
  • 原文地址:https://www.cnblogs.com/ZhenghangHu/p/9165731.html
Copyright © 2011-2022 走看看