1. 程式人生 > >codeforces 990D、Graph And Its Complement(思維)

codeforces 990D、Graph And Its Complement(思維)

                                                             D. Graph And Its Complement

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Given three numbers n,a,bn,a,b. You need to find an adjacency matrix of such an undirected graph that the number of components in it is equal to aa, and the number of components in its complement is bb. The matrix must be symmetric, and all digits on the main diagonal must be zeroes.

In an undirected graph loops (edges from a vertex to itself) are not allowed. It can be at most one edge between a pair of vertices.

The adjacency matrix of an undirected graph is a square matrix of size nn consisting only of "0" and "1", where nn is the number of vertices of the graph and the ii-th row and the ii-th column correspond to the ii-th vertex of the graph. The cell (i,j)(i,j) of the adjacency matrix contains 11 if and only if the ii-th and jj-th vertices in the graph are connected by an edge.

A connected component is a set of vertices XX such that for every two vertices from this set there exists at least one path in the graph connecting this pair of vertices, but adding any other vertex to XX violates this rule.

The complement or inverse of a graph GG is a graph HH on the same vertices such that two distinct vertices of HH are adjacent if and only if they are not adjacent in GG.

Input

In a single line, three numbers are given n,a,b(1≤n≤1000,1≤a,b≤n)n,a,b(1≤n≤1000,1≤a,b≤n): is the number of vertexes of the graph, the required number of connectivity components in it, and the required amount of the connectivity component in it's complement.

Output

If there is no graph that satisfies these constraints on a single line, print "NO" (without quotes).

Otherwise, on the first line, print "YES"(without quotes). In each of the next nn lines, output nn digits such that jj-th digit of ii-th line must be 11 if and only if there is an edge between vertices ii and jj in GG (and 00 otherwise). Note that the matrix must be symmetric, and all digits on the main diagonal must be zeroes.

If there are several matrices that satisfy the conditions — output any of them.

Examples

input

Copy

3 1 2

output

Copy

YES
001
001
110

input

Copy

3 3 3

output

Copy

NO

一、原題地址

點我傳送

二、大致題意

給出n,a,b。表示有n個城鎮現在要構造一副圖,使得原圖連通塊的數量為a。把原圖上所有邊去掉再補上原來圖上沒有的邊(即補圖)的連通塊數量為b。

三、大致思路

  首先在a和b中一定會有一個數的值為1。證明很簡單,對於一副圖中的一個連通塊 x ,對於這個連通塊中的點,當這個點取補圖的時候,它會與其他連通塊的所有點連一條邊,這個連通塊 x 當中的其他點也是如此,那麼其實就相當於把所有的點都匯在了一起變成一個連通塊。

那麼其實情況就不會很多了,要麼a=1,要麼b=1,要麼a和b都等於1。

1、當b=1時,只需要考慮原本的圖是怎麼樣的就行,那麼只需要把前a-1個點獨立出去,然後再把後面的點連通成一塊就行。

2、當a=1時,情況其實和1是一樣的,可以選擇去構造補圖,相當於所有操作全部取反就行。

3、a和b都等於1時,n=1肯定是可以的,n=2或者n=3都不行,但是n>=4時只需要把圖構造成一條鏈,又可以了。

4、a和b都不等於1已經討論過了不行。

四、程式碼

#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<cstring>
#include<algorithm>
#include<queue>
#include<vector>
#include<functional>
using namespace std;
#define inf 0x3f3f3f3f
typedef long long LL;
int gcd(int a, int b) { return a == 0 ? b : gcd(b % a, a); }
LL GCD(LL a, LL b) { return a == 0 ? b : GCD(b % a, a); }

int n, a, b;
int mmp[1005][1005];
void printmap()
{
	for (int i = 1; i <= n; i++)
	{
		for (int j = 1; j <= n; j++)
		{
			if (i == j)printf("0");
			else printf("%d", mmp[i][j]);
		}
		printf("\n");
	}
}
int main()
{
	scanf("%d %d %d", &n, &a, &b);
	memset(mmp, 0, sizeof(mmp));
	if (a != 1 && b != 1)
	{
		printf("NO\n");
	}
	else if (a == 1 && b != 1)
	{
		for (int i = 1; i <= n; i++)
			for (int j = 1; j <= n; j++)
				mmp[i][j] = 1;
		for (int i = b; i <= n; i++)
			mmp[i][n] = mmp[n][i] = 0;
		printf("YES\n");
		printmap();
	}
	else if (b == 1 && a != 1)
	{
		for (int i = a; i <= n; i++)
			mmp[i][n] = mmp[n][i] = 1;
		printf("YES\n");
		printmap();
	}
	else if (a == 1 && b == 1)
	{
		if (n == 1)
		{
			printf("YES\n");
			printf("0\n");
		}
		else if (n == 2 || n == 3)
		{
			printf("NO\n");
		}
		else
		{
			printf("YES\n");
			for (int i = 1; i <= n - 1; i++)
				mmp[i][i + 1] = mmp[i + 1][i] = 1;
			printmap();
		}
	}
	getchar();
	getchar();

}