Codeforces 990D - Graph And Its Complement
传送门:http://codeforces.com/contest/990/problem/D
这是一个构造问题。
构造一张n阶简单无向图G,使得其连通分支个数为a,且其补图的连通分支个数为b。
对于一张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}。
参考程序如下:
#include <bits/stdc++.h> using namespace std; #define MAX_N 1000 bool adj[MAX_N][MAX_N]; int main(void) { int n, a, b; cin >> n >> a >> b; bool flag = 1; if (a != 1 && b != 1) flag = 0; if ((n == 2 || n == 3) && (a + b == 2)) flag = 0; if (!flag) { cout << "NO" << endl; return 0; } cout << "YES" << endl; if (b == 1) { memset(adj, 0, sizeof(adj)); for (int i = a; i < n; i++) { adj[i - 1][i] = 1; adj[i][i - 1] = 1; } } else { memset(adj, -1, sizeof(adj)); for (int i = 0; i < n; i++) adj[i][i] = 0; for (int i = b; i < n; i++) { adj[i - 1][i] = 0; adj[i][i - 1] = 0; } } for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) putchar(adj[i][j]? '1': '0'); putchar('\n'); } }
posted on 2018-06-12 13:39 SiuGinHung 阅读(347) 评论(0) 编辑 收藏 举报