1. 程式人生 > >【打CF,學演算法——三星級】CodeForces 550D Regular Bridge (構造)

【打CF,學演算法——三星級】CodeForces 550D Regular Bridge (構造)

題面:

D. Regular Bridge time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output

An undirected graph is called k-regular, if the degrees of all its vertices are equalk. An edge of a connected graph is called abridge, if after removing it the graph is being split into two connected components.

Build a connected undirected k-regular graph containing at least one bridge, or else state that such graph doesn't exist.

Input

The single line of the input contains integer k (1 ≤ k ≤ 100) — the required degree of the vertices of the regular graph.

Output

Print "NO" (without quotes), if such graph doesn't exist.

Otherwise, print "YES" in the first line and the description of any suitable graph in the next lines.

The description of the made graph must start with numbers n and m — the number of vertices and edges respectively.

Each of the next m lines must contain two integers,a and b (1 ≤ a, b ≤ n,a ≠ b), that mean that there is an edge connecting the verticesa

and b. A graph shouldn't contain multiple edges and edges that lead from a vertex to itself. A graph must be connected, the degrees of all vertices of the graph must be equalk. At least one edge of the graph must be a bridge. You can print the edges of the graph in any order. You can print the ends of each edge in any order.

The constructed graph must contain at most 106 vertices and106 edges (it is guaranteed that if at least one graph that meets the requirements exists, then there also exists the graph with at most106 vertices and at most106 edges).

Examples Input
1
Output
YES
2 1
1 2
Note

In the sample from the statement there is a suitable graph consisting of two vertices, connected by a single edge.


題意:

    求構造一個無向圖,圖中每個節點的度數都為k,且該圖存在至少一個割邊,即斷開後,圖不連通。k小於等於100,要求構造的圖中,點數不大於10^6,且邊數也不大於10^6。

解題:

     先畫一條割邊,割邊上的一點A,必然會有另外K-1條邊連出去,對於A這一側,設還需新增a個節點,x條邊,根據度數和邊的關係可得。(k-1)*(k-1)+k*a=2*x,明顯(k-1)*(k-1)為偶數,欲使等式有解,最小的a取值為2。明顯當k為奇數無解。

      於是開始構造,A側新加2個節點,將這兩個節點與k-1個節點相連,且兩個節點間連一條邊,這兩點已符合度數要求,剩餘的k-1個點通過迴圈後連的方式補足剩餘度數即可,B側同理。

程式碼:

#include <iostream>
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <cstdio>
#include <vector>
#define pe(u,v) printf("%d %d\n",u,v)
using namespace std;
void show(int x,int y,int t)
{
	int tmp;
	for(int i=x;i<=y;i++)
	{
		for(int j=1;j<=t;j++)
		{
			tmp=i+j;
			if(tmp>y)
				tmp=tmp-y+x-1;
			pe(i,tmp);
		}
	}
}
int main()
{
    int k;
	scanf("%d",&k);
	if(k%2)
	{
		printf("YES\n");
		if(k==1)
			printf("2 1\n1 2\n");
        else
		{
			printf("%d %d\n",2*k+4,k*k+2*k);
			for(int i=1;i<=k-1;i++)
		    {
				pe(1,i+1);
				pe(k+1,i+1);
				pe(k+2,i+1);
			}
			pe(k+1,k+2);
			show(2,k,(k-3)/2);
			pe(1,k+3);
			for(int i=1;i<=k-1;i++)
			{
				pe(k+3,k+3+i);
				pe(2*k+3,k+3+i);
				pe(2*k+4,k+3+i);
			}
			pe(2*k+3,2*k+4);
			show(k+4,2*k+2,(k-3)/2);
		}
	}
	else
		printf("NO\n");
	return 0;
}