• 2019ICPC上海Spanning Tree Removal构造题


    刚打完2021杭电多校6,有个构造,当时没有做,回头看了一波巨佬的博客学了一手,在这里记录一下
    题目链接

    链接:https://ac.nowcoder.com/acm/contest/4370/D
    来源:牛客网
    spj

    题目描述

    Bob has recently learned algorithms on finding spanning trees and wanted to give you a quiz.

    To recap, a spanning tree is a subset of graph {G}G, which has all the vertices covered with minimum possible number of edges. Hence, a spanning tree does not have cycles and it cannot be disconnected. Given an arbitrary undirected simple graph (without multiple edges and loops), a spanning tree removal is defined as: retrieve one spanning tree of the graph, and remove all the edges selected by the spanning tree from the original graph, obtaining a new graph.

    Bob found "spanning tree removal’’ so fun that he wanted to do it over and over again. In particular, he began with a complete graph, i.e., a graph with every pair of distinct vertices connected by a unique edge. Your goal, is to smartly choose spanning trees to remove so that you can repeat as many times as possible until there is no longer a spanning tree in the graph.

    输入描述:

    在这里插入图片描述

    输出描述:

    在这里插入图片描述

    示例1
    输入

    3
    2
    3
    4
    

    输出

    Case #1: 1
    1 2
    Case #2: 1
    3 1
    1 2
    Case #3: 2
    1 3
    3 4
    2 4
    3 2
    1 4
    2 1
    

    本题是一个spj的问题
    题意是给定一个完全图,包含了n个节点,每次可以在这个图中选择一个生成树,然后将该生成树的所有边都删除,然后得到一个新图,然后再从新的图中重复上述操作,问最多可以操作多少次,对于每一次操作,输出选择的生成树中的所有边(n-1行)

    在lc哥的图中稍加改造,做成这个样子:
    图中有6个点,将点按照0 -> 5编号

    在这里插入图片描述
    pre指的是上一个到达的节点编号
    比如我们选择从0结点开始
    0 -> 0 + 10 -> 1
    1 -> 1 - 21 -> 5
    5 -> 5 + 35 -> 2
    2 -> 2 - 42 -> 4
    4 -> 4 + 54 -> 3
    注意这里有个( +n)%n的过程
    由于节点从1开始编号,所以说,我们将左右两边+1即可
    对于最多可以操作多少次的问题,我们可以从起点的选择来进行考虑,其中有n个节点,去掉重复的一半,只会有n/2(下取整)个
    比如在上面有6个点的图中,从0开始和从3开始得到的图是一样的

    code:
    在这里插入图片描述

    #include <iostream>
    
    using namespace std;
    #define in(x) cin>>x
    typedef long long ll;
    
    int main(){
        int _;in(_);
        int cnt = 0;
        while(_--){
            int n;in(n);
            ++ cnt;
            printf("Case #%d: %d
    ",cnt,n>>1);
            for(int i=1;i<=n/2;i++){
                int pre = i;
                int sign = 1;
                int now = i;
                for(int j=1;j<=n-1;j++){
                    pre = now;
                    now = (pre + sign * j + n) % n;
                    printf("%d %d
    ",pre+1,now+1);
                    sign *= -1;
                }
            }
        }
        
        return 0;
    }
    
  • 相关阅读:
    使用remove_constants工具查看Oracle是否使用绑定变量
    v$sqlarea,v$sql,v$sqltext这三个视图提供的sql语句有什么区别?
    Cardinality (基数)
    分区表操作
    递归连接查询
    解决Android应用安装快完毕时提示签名冲突,android签名文件生成(转)
    Oracle的Numer类型与C,C#数据类型对应关系
    Spring学习(四)——使用Spring JDBC访问数据库
    Spring学习(三)——集成 Velocity
    Spring学习(二)——使用Gradle构建一个简单的Spring MVC Web应用程序
  • 原文地址:https://www.cnblogs.com/PushyTao/p/15459822.html
Copyright © 2020-2023  润新知