zoukankan      html  css  js  c++  java
  • Codeforces 550D —— Regular Bridge——————【构造】

     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 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 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).

    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。如果有这样的图,输出顶点数和边数,同时还有所有边的端点。

    解题思路:首先我们证明k不能是偶数,假设结点u和v关于一条桥邻接,那么如果去掉该桥后,对于包含u结点的连通分量来说,只有u结点是奇数,那么这与连通分量中所有结点的度的和为偶数相矛盾,得证k只能为奇数。

        讨论k为奇数:我们假定结点1是由桥所连接的结点,那么想让1结点度数为k,那么就要有k-1个结点与1邻接,我们假设是2->k,这k-1个结点就算是行成完全图也不能保证度数为k,所以需要加一个结点k+1,让k+1先与2->k这k-1个结点相连,但是k+1结点的度才为k-1,所以我们仍然需要加结点k+2,让k+2也与2->k都连接,同时让k+1与k+2连接。保证了k+1和k+2度都为k。但是这时候2->k这k-1个结点度数都才为3。如果让2->k这k-1个结点行成完全图,那么每个结点会增加k-2个度,但是现在需要每个结点增加k-3个度,所以需要每个结点减少1个度。我们可以假设删去2 -> 3, 4 -> 5,6->7.....这些边。到这里我们的构造算法已经结束了。

        构造算法为:让1、k+1、k+2跟2->k这k-1个结点邻接,同时让2->k这k-1个结点形成完全图,但是删除env->env+1,env为2->k中所有偶数。同时桥所连接的那一边是对称的处理。

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<math.h>
    #include<string>
    #include<iostream>
    #include<queue>
    #include<stack>
    #include<map>
    #include<vector>
    #include<set>
    using namespace std;
    typedef long long LL;
    #define mid (L+R)/2
    #define lson rt*2,L,mid
    #define rson rt*2+1,mid+1,R
    #pragma comment(linker, "/STACK:102400000,102400000")
    const int maxn = 1e5 + 300;
    const int INF = 0x3f3f3f3f;
    typedef long long  LL;
    typedef unsigned long long ULL;
    int main() {
        int k;
        scanf ( "%d", &k );
        if ( k == 1 ) {
            puts ("YES
    2 1
    1 2");
        }else if ( k % 2 == 0 ) {
            puts ( "NO" );
        }else {
            puts ( "YES" );
            printf ( "%d %d
    ", 2*k + 4, k*(k+2) );
            for ( int i = 2; i <= k; i++ ) {
                printf ( "1 %d
    ", i );
            }
            int nn = k + 2;
            for ( int i = 2; i <= k; i++ ) {
                printf("%d %d
    ",i, k+1);
                printf("%d %d
    ",i, k+2);
                for ( int j = i + 1; j <= k; j++ ) {
                    if(i%2 == 0 && j == i+1) continue;
                    printf ( "%d %d
    ", i, j );
                }
            }
            printf ( "%d %d
    ", k + 1, k + 2 );
            
            for ( int i = 2; i <= k; i++ ) {
                printf ( "%d %d
    ", 1 + nn, i + nn );
            }
            for ( int i = 2; i <= k; i++ ) {
                printf("%d %d
    ",i+nn, nn+k+1);
                printf("%d %d
    ",i+nn, nn+k+2);
                for ( int j = i + 1; j <= k; j++ ) {
                    if(i%2 == 0 && j == i+1) continue;
                    printf ( "%d %d
    ", i + nn, j + nn );
                }
            }
            printf ( "%d %d
    ", k + 1 + nn, k + 2 + nn );
            printf ( "%d %d
    ", 1, nn + 1 );
        }
        return 0;
    }
    

      

  • 相关阅读:
    2019高考数学理科Ⅱ卷解析版[解答题]
    对风说爱你
    佛教人生-伴侣
    【Echarts每天一例】-1
    算法中涉及的专业英语
    python--随机函数(random,uniform,randint,randrange,shuffle,sample)
    【linux shell系列--1】crontab命令
    【Python爬虫实战--3】html写正则表达式
    mysql启动参数 skip-grant-tables
    php通过反射执行某方法
  • 原文地址:https://www.cnblogs.com/chengsheng/p/5543684.html
Copyright © 2011-2022 走看看