CF Regular Bridge()

来源:互联网 发布:lcdp0端口定义 编辑:程序博客网 时间:2024/04/29 16:05
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 equal k. An edge of a connected graph is called a bridge, 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 ≤ na ≠ b), that mean that there is an edge connecting the vertices a 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 equal k. 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 and 106 edges (it is guaranteed that if at least one graph that meets the requirements exists, then there also exists the graph with at most 106 vertices and at most 106 edges).

Sample test(s)
input
1
output
YES2 11 2
Note

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

题意:给出一个k,要求能不能构建一个图,使所有的点的度数为k,并且图中至少有一个桥。

#include<stdio.h>int main(){    int n,k,i,j;    while(scanf("%d",&k) != EOF)    {        if(k%2 == 0) //每个点的度数为偶,则不能构成满足条件的图        {            printf("NO\n");            continue;        }        printf("YES\n");        if(k == 1)        {            printf("%d %d\n%d %d\n",2,1,1,2);            continue;        }        n=k+2; //桥的两头是对称的两部分,n是一个部分的点数        printf("%d %d\n",n*2,n*k);        for(int i=n; i>n-3; i--)            for(int j=1; j<=k-1; j++)//1~(k-1)个点连接3条边            printf("%d %d\n",i,j);        printf("%d %d\n",n-1,n-2);        //还有k-1个点需要k-3个度,可以连接的点除本身还有k-2个点可连接,所以必有交替 (跳一个点,不跳,跳,……)        for(int i=1; i<=(k-1)-2; i++){//后两个点己经确定,无需连边,因为在前方己有k-3个点相连            int j;            if(i%2)j=i+2;//跳一个点            else j=i+1;            while(j<=k-1){                printf("%d %d\n",i,j); j++;            }        }        printf("%d %d\n",n,n+n);//桥        //对称部分,只要对输出的每个数加一个n       for(int i=n; i>n-3; i--)            for(int j=1; j<=k-1; j++)            printf("%d %d\n",n+i,n+j);        printf("%d %d\n",n+n-1,n+n-2);        for(int i=1; i<=(k-1)-2; i++){            int j;            if(i%2)j=i+2;            else j=i+1;            while(j<=k-1){                printf("%d %d\n",n+i,n+j); j++;            }        }    }    return 0;}


0 0
原创粉丝点击