CSP 201512-4 送货

简介: CSP 201512-4 送货

问题描述

image.png

输入格式

image.png

输出格式

image.png

数据范围

image.png

输入样例1:

4 5
1 2
1 3
1 4
2 4
3 4

输出样例1:

1 2 4 1 3 4

样例1解释

城市的地图和小明的路径如下图所示。

image.png

输入样例2:

4 6
1 2
1 3
1 4
2 4
3 4
2 3

输出样例2:

-1

样例2解释

城市的地图如下图所示,不存在满足条件的路径。

image.png

本题链接http://118.190.20.162/view.page?gpid=T34

AC代码

C++

#include <iostream>
#include <cstring>
#include <algorithm>
#include <set>
using namespace std;
const int N = 10010, M = 100010;
int n, m;
set<int> g[N];
int p[N];
int ans[M], top;
int find(int x)      // 并查集
{
    if (p[x] != x) p[x] = find(p[x]);
    return p[x];
}
void dfs(int u)
{
    while (g[u].size())
    {
        int t = *g[u].begin();
        g[u].erase(t), g[t].erase(u);  // 删边
        dfs(t);
    }
    ans[ ++ top] = u;
}
int main()
{
    scanf("%d%d", &n, &m);
    for (int i = 1; i <= n; i ++ ) p[i] = i;   // 初始化p数组
    while (m -- )
    {
        int a, b;
        scanf("%d%d", &a, &b);
        g[a].insert(b), g[b].insert(a);
        p[find(a)] = find(b);
    }
    int s = 0;
    for (int i = 1; i <= n; i ++ )
        if (find(i) != find(1))      // 不是连通图
        {
            puts("-1");
            return 0;
        }
        else if (g[i].size() % 2) s ++ ; // s记录的是度数为奇数的点的
    // 度数为奇数的点不是0个或2个,或者度数为奇数的点为2个但是起点的度数不是奇数,则不符合欧拉路径
    if (s != 0 && s != 2 || s == 2 && g[1].size() % 2 == 0)
    {
        puts("-1");
        return 0;
    }
    dfs(1);    // 开始遍历欧拉路径
    for (int i = top; i; i -- )   // 欧拉路径实际上记录的是倒序,故求正向欧拉路径需要逆序输出
        printf("%d ", ans[i]);
    return 0;
}

java

注:java版代码只有50分

import java.util.*;
public class Main {
    final int N = 100010;
    int n, m;
    int[] ans = new int[N];
    int top;
    int[] p = new int[10010];
    TreeSet[] g = new TreeSet[10010];
    void run() {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        m = sc.nextInt();
        for (int i = 0; i <= n; i++) {
            g[i] = new TreeSet();
        }
        for (int i = 1; i <= n; i++) {
            p[i] = i;
        }
        while (m -- != 0) {
            int a, b;
            a = sc.nextInt();
            b = sc.nextInt();
            g[a].add(b);
            g[b].add(a);
            p[find(a)] = find(b);
        }
        int s = 0;
        for (int i = 1; i <= n; i++) {
            if (find(i) != find(1)) {
                System.out.println("-1");
                return;
            } else if (g[i].size() % 2 != 0)  {
                s++;
            }
        }
        if (s != 0 && s != 2 || (s == 2 && g[1].size() % 2 == 0)) {
            System.out.println("-1");
            return;
        }
        dfs(1);
        for (int i = top; i != 0; i--) {
            System.out.printf("%d ", ans[i]);
        }
    }
    void dfs(int u) {
        while (g[u].size() != 0) {
            int t = (Integer) g[u].first();
            g[u].remove(t);
            g[t].remove(u);
            dfs(t);
        }
        ans[ ++ top] = u;
    }
    int find(int x) {
        if (p[x] != x) {
            p[x] = find(p[x]);
        }
        return p[x];
    }
    public static void main(String[] args) {
        new Main().run();
    }
}

代码解释

从一个点出发,不重不漏的经过图中每一条边的一条路径(允许多次经过同一个点)。

从一个点出发,不重不漏的经过图中每一条边的一条路径(允许多次经过同一个点)。如果此路径的起点和终点相同,则称其为一条欧拉回路。

入度(indegree)就是有向图中指向这个点的边的数量,即有向图的某个顶点作为终点的次数和

出度(outdegree)就是从这个点出去的边的数量,即有向图的某个顶点作为起点的次数和

一个点的度(degree)指图中与该点相连的边数

无向连通图

欧拉回路:所有点的度数都为偶数即为有欧拉回路

欧拉路径:度数为奇数的点要么有2个要么有0个

若为0个那么从任意点出发都可以,如果有2个,那么起点必须是其中一个点,终点必须为另一个点


有向连通图

欧拉回路:所有点的入度等于出度

欧拉路径:1.所有点的入度等于出度 2.有一个点(终点)的入度=出度+1,且存在一个点(起点)的出度=入度+1


从当前点出发,只要有出去的边就往外走,深度优先遍历,回溯路径就是它的一个方案

为什么从起点搜到终点不是一个方案?

因为在搜索的过程中,不一定会把所有的边全部走到(有一堆额外的环),但因为起点和终点是唯一的,

且其余点的度数均为偶数,故我们在回溯的过程中把其他的结点(那些没有走过的环)补充到搜索图中即可

字典序最小:从当前点出去搜的时候,按照编号从小到大搜索一遍,就可以保证字典序最小


欧拉路径证明(无向图)

对于起点而言,设其度数为n,那么起始往出走需要一条边,其余到达起点的话,就必然是进来一次出去一次,故起点的度数必须是奇数

对于终点而言,设其度数为m,那么最终到达需要一条边,其余到达终点的点,需要再次出去,故终点的度数必须是奇数

对于非起点和非终点的其余点,它们只是作为中间的“桥梁”,故到达这些点后还需要离开,故这些点的度数必须是偶数

如果起点和终点是同一个点,那么对于起点(终点)而言,出去需要一条边,最终到达该点需要一条边,其余时候进来必然还要出去,

故在这种情况下,起点(终点)的度为偶数

综上所述,对于一个无向图的欧拉路径而言,度数为奇数的点要么为2个要么为0个,且为2个的时候,这两个点分别做起点和终点

    dfs(u)   // 求得的序列其实是欧拉路径的倒序序列
    {
        for u的所有边
            dfs()  // 扩展
        seq += u   // 把u加到序列中
    }

欧拉路径dfs和一般图论dfs区别:

一般图论dfs用点来判重,时间复杂度在O(n+m)

欧拉路径是用边来判重,如果用一个bool变量来表示每个边是否被搜过,时间复杂度会很高:

举个例子,对于一个点,假设其有m条自环,那么我们在遍历的过程中搜第一条边,搜完之后又回到该点,

此时第一条边已经被用过了,故我们要跳过这一条边搜第二条边,依次类推,在搜第三条边的时候需要跳过第一条边和第二条边

以此类推,在搜完m条边的时候就会跳m^2次,这样对于1e5的数据量显然就会超时

处理方法:每用一条边不是进行简单的标记,而是直接进行删除,这样就可以降为线性时间复杂度

无向图的删除方法:因为建无向图对于每一条边会建立两次(不同方向),故我们在删除的时候还需要对它的反向边进行一次标记

如何根据一条边找到它的反向边:因为建边的时候是按照(0,1),(2,3)…进行建边,故求反向边可直接根据 i^1 求得

上述代码中并未采取这种建边方式,直接把边放入set中,set自然有序,且易直接删边


目录
相关文章
|
12月前
|
JavaScript
Threejs实现PMD模型眨眼说话等功能
这篇文章详细介绍了如何在Three.js中实现PMD模型的眨眼和说话等动态效果,通过控制模型的关键帧来模拟面部表情的变化。
329 0
Threejs实现PMD模型眨眼说话等功能
|
12月前
|
传感器 物联网 区块链
未来已来:探索新兴技术的发展趋势与应用场景
【10月更文挑战第2天】本文将深入探讨区块链技术、物联网(IoT)以及虚拟现实(VR)等新兴技术的最新发展趋势和潜在应用场景。我们将通过具体案例,分析这些技术如何影响我们的生活和工作方式,并讨论它们在未来可能带来的变革。文章旨在为读者提供一个关于这些技术如何塑造我们未来的清晰视角。
|
安全 数据安全/隐私保护 Python
版权保卫战的新武器!揭秘数字水印如何成为知识产权的守护神!
【8月更文挑战第22天】数字水印技术在知识产权保护中至关重要。它通过在数字媒体中嵌入不可见信息(如版权标识),在不影响原内容的前提下实现作品的版权保护、防篡改及非法分发追踪。本文将概述数字水印的概念、技术原理(包括空间域与频域方法),并提供Python代码示例展示水印的嵌入与提取过程。此外,还将分享一个出版社如何运用数字水印成功维护自身版权的真实案例,以此展现数字水印在实际应用中的价值与潜力。
561 0
|
安全 Windows
Windows 无法连接打印机,请检查打印机名并重试。如果这是网络打印机,请确保打印机已打开,并且打印机地址正确。报错代码:0x00000709
Windows 无法连接打印机,请检查打印机名并重试。如果这是网络打印机,请确保打印机已打开,并且打印机地址正确。报错代码:0x00000709
Windows 无法连接打印机,请检查打印机名并重试。如果这是网络打印机,请确保打印机已打开,并且打印机地址正确。报错代码:0x00000709
|
监控 安全 网络安全
云端防御策略:在云计算中确保数据安全与隐私
【4月更文挑战第6天】 随着企业和个人日益依赖云服务,数据安全性和隐私保护成为不容忽视的挑战。本文探讨了云计算环境中面临的主要网络安全威胁,并提出了综合性的安全措施来加强防护。我们将从云服务的基础知识出发,分析安全风险,并深入讨论如何通过加密技术、身份验证、访问控制以及持续监控等手段来提高数据的安全性。文章的目标是为读者提供一套实用的策略框架,以便在享受云计算带来的便利时,能够有效地保障信息安全。
|
SQL 网络协议 关系型数据库
|
vr&ar 图形学 异构计算
GLTF编辑器如何合并相同材质的Mesh
建议在创建模型时尽量避免过多使用相同的材质。可以考虑使用材质实例化或者共享材质的方式,来降低模型中的材质数量,并优化渲染及文件大小等方面的性能
343 0
|
小程序 安全 前端开发
《钉钉应用开发者速成手册》之“API实战——搭建审批工作流”
本教程以一个简单的出差审批工作流为例展示如何发起一个审批。为了方便开发者体验,我们提供了服务端和前端代码,您只需要根据本文档的操作,完成基础配置既可。
4186 0
《钉钉应用开发者速成手册》之“API实战——搭建审批工作流”
|
API 开发者 数据可视化
开放平台能为开发者带来什么价值?
2019杭州云栖大会大咖有约,由阿里云开放平台负责人圭多带来以“开放平台能为开发者带来什么价值?”为题的演讲。本文对阿里云的开放平台进行了详细的阐述,即对阿里云开放平台到底开放的是什么,开发者又被给予了哪些开发能力进行了详细的介绍,包括丰富完整的API产品体系,及如何让开发者更好享受技术红利?
|
Oracle 关系型数据库 数据库
PostgreSQL(PPAS 兼容Oracle) 从零开始入门手册 - 珍藏版
标签 PostgreSQL , edb , ppas , Oracle 兼容 背景 云数据库PPAS版,是阿里云与EnterpriseDB公司(简称EDB)合作基于PostgreSQL高度兼容Oracle语法的数据库服务,为用户提供易于操作的迁移工具,兼容范围涵盖:PL/SQL、数据类型、高级函数、表分区等。
4760 0