http://codeforces.com/problemset/problem/990/D
题意:
构造一张n阶简单无向图G,使得其连通分支个数为a,且其补图的连通分支个数为b。
题解:
第一眼看到题,一脸懵,嗯?这让我怎么建图???
还是菜啊,看别人的题解学习学习吧。。。
参考于:https://www.cnblogs.com/siuginhung/p/9172602.html
这是一个构造问题。
对于一张n阶简单无向图G,若此图不连通,则其补图是连通的。
证明:
首先,在简单无向图G中,若结点u、v(u≠v)不连通,则在其补图中,u、v必然连通。
将图G=<V,E>划分为k个连通分支,Gi=<Vi,Ei>,i=1,2,...,k。在V中任取两点u、v(u≠v)。
若u∈Vi,v∈Vj,且i≠j,则u、v在图G中不连通,则u、v必然在其补图中连通;
若u,v∈Vi,则必然存在w∈Vj,且i≠j,使得u、w和v、w在补图中连通。
于是,在题中,a、b中至少有一个为1。
接下来构造连通分支:若一个n阶简单无向图有k(k≥2)个连通分支,则可以构造其连通分支分别为{1},{2},...,{k-1},{k,k+1,...,n}。
代码如下:
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <string> 5 #include <math.h> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <set> 11 #include <map> 12 #include <sstream> 13 const int INF=0x3f3f3f3f; 14 typedef long long LL; 15 #define Bug cout<<"---------------------"<<endl 16 const int mod=1e9+7; 17 const int maxn=2e5+10; 18 using namespace std; 19 20 int G[1005][1005]; 21 22 int main() 23 { 24 int n,a,b; 25 scanf("%d %d %d",&n,&a,&b); 26 if((a!=1&&b!=1)||(n==2||n==3)&&(a==1&&b==1)) 27 printf("NO "); 28 else 29 { 30 printf("YES "); 31 if(a==1) 32 { 33 for(int i=1;i<=n;i++) 34 { 35 G[i][i]=0; 36 for(int j=i+1;j<=n;j++) 37 G[i][j]=G[j][i]=1; 38 } 39 for(int i=b;i<n;i++) 40 G[i][i+1]=G[i+1][i]=0; 41 } 42 else 43 { 44 memset(G,0,sizeof(G)); 45 for(int i=a;i<n;i++) 46 { 47 G[i][i+1]=G[i+1][i]=1; 48 } 49 } 50 for(int i=1;i<=n;i++) 51 { 52 for(int j=1;j<=n;j++) 53 printf("%d",G[i][j]); 54 printf(" "); 55 } 56 } 57 return 0; 58 }