AtCoder Beginner Contest 396(d和e)

news/2025/3/9 16:38:52/文章来源:https://www.cnblogs.com/fufuaifufu/p/18760701

题目链接d

题目分析

本题要求在一个简单连通无向图中,找出从顶点 1 到顶点 N 的所有简单路径(即不重复经过同一顶点的路径)中,路径上所有边的标签的异或值的最小值。

输入信息

  • 第一行包含两个整数 NM,分别表示图的顶点数和边数,其中 2 ≤ N ≤ 10N - 1 ≤ M ≤ N * (N - 1) / 2
  • 接下来的 M 行,每行包含三个整数 u_iv_iw_i,表示顶点 u_iv_i 之间有一条标签为 w_i 的边,其中 1 ≤ u_i < v_i ≤ N0 ≤ w_i < 2^60

输出信息

输出从顶点 1 到顶点 N 的所有简单路径中,边标签异或值的最小值。

解题思路

由于顶点数 N 最大为 10,所以可以使用深度优先搜索(DFS)来遍历所有从顶点 1 到顶点 N 的简单路径,并计算每条路径上所有边的标签的异或值,最后取最小值。

具体步骤如下:

  1. 构建图的邻接表:使用邻接表来存储图的结构,其中每个顶点的邻接表存储了与该顶点相邻的顶点以及对应的边的标签。
  2. 初始化变量:初始化一个布尔数组 visited 来标记每个顶点是否被访问过,以及一个变量 min_xor 来记录最小的异或值,初始值设为 LLONG_MAX
  3. 深度优先搜索:从顶点 1 开始进行深度优先搜索,对于每个未访问过的相邻顶点,递归调用 DFS 函数,并更新当前的异或值。当到达顶点 N 时,更新最小异或值。
  4. 回溯:在递归返回时,将当前顶点标记为未访问,以便尝试其他路径。
  5. 输出结果:最后输出最小异或值。

代码实现

#include <bits/stdc++.h>
using namespace std;
using ll = long long;// 定义邻接表,存储图的结构
vector<pair<int, ll>> adj[10];
// 标记每个顶点是否被访问过
bool visited[10];
// 记录最小的异或值
ll min_xor = LLONG_MAX;// 深度优先搜索函数
void dfs(int u, int N, ll current_xor) {// 如果到达顶点 N,更新最小异或值if (u == N - 1) {min_xor = min(min_xor, current_xor);return;}// 标记当前顶点为已访问visited[u] = true;// 遍历当前顶点的所有相邻顶点for (auto &[v, w] : adj[u]) {// 如果相邻顶点未被访问过if (!visited[v]) {// 递归调用 DFS 函数,并更新当前的异或值dfs(v, N, current_xor ^ w);}}// 回溯,将当前顶点标记为未访问visited[u] = false;
}int main() {int N, M;cin >> N >> M;// 读取每条边的信息,并构建图的邻接表for (int i = 0; i < M; i++) {int u, v;ll w;cin >> u >> v >> w;// 顶点编号从 0 开始,所以减 1u--; v--;adj[u].push_back({v, w});adj[v].push_back({u, w});}// 初始化 visited 数组为 falsememset(visited, false, sizeof(visited));// 从顶点 0 开始进行深度优先搜索,初始异或值为 0dfs(0, N, 0);// 输出最小异或值cout << min_xor << endl;return 0;
}

注意事项

  • 由于边的标签 w_i 可能非常大,需要使用 long long 类型来存储。

题目链接e

题目概述

问题描述
给定以下输入:
(N):序列 (A) 的长度
(M):约束条件的数量
三个长度为 (M) 的序列:(X)、(Y) 和 (Z),对于每个 (i)(1≤i≤M):
AXi⊕AYi=Zi(其中 ⊕表示异或运算)
任务:
判断是否存在一个非负整数序列 A=(A1,A2,…,AN),使得所有约束条件都得到满足
如果存在,找到一个使 数组A和最小的序列。
如果不存在,输出 −1
解题思路

  1. 理解异或约束
    异或运算的性质是:若 A⊕B=C,则 A=B⊕C 或 B=A⊕C
    。这意味着给定一个约束 AXi⊕AYi=Zi,如果我们确定了 AXi,就可以计算 AYi,反之亦然。问题的核心在于:
  • 确保所有 (M) 个约束条件之间的一致性。

  • 在满足约束时,最小化序列的总和。

  1. 建模为图
    我们可以将问题抽象为一个无向图:
  • 节点:序列中的位置 1,2,…,N,对应 A1,A2,…,AN
  • 边:每个约束 AXi⊕AYi=Zi表示一条连接 Xi和 Yi的边,边的“权重”为 Zi
    ,表示异或关系。
    图可能包含多个连通分量,每个连通分量内的值必须满足所有相关约束。
  1. 检查一致性
    要确保序列 (A) 存在,必须验证图中每个连通分量的赋值一致性。如果一个节点可以通过多条路径到达,则通过不同路径计算出的值必须相等。我们使用DFS来检查这一点。
  2. 最小化总和
    由于 Ai是非负整数,最小值为 0。我们的目标是使每个 Ai尽可能小:
    为每个连通分量分配初始值(例如从 0 开始)
    根据约束传播值。
    通过调整整个连通分量的值(异或一个常数),使总和最小化

解决方案步骤
步骤 1:构建图
对于每个约束 (i),在节点 Xi和 Yi之间添加一条边,权重为 Zi
使用邻接表存储图。
步骤 2:DFS 遍历与一致性检查
对于每个未访问的节点,运行 DFS:

  • 从当前节点(设为根 (u))开始,假设 Au=0
  • 对于每个邻居 (v)(边权重为 (w)),计算 Av=Au⊕w
  • 如果 (v) 未访问,继续递归。
  • 如果 (v) 已访问,检查 Av是否等于 Au⊕w若不相等,则约束不一致,返回 −1

步骤 3:最小化总和

  • DFS 确定每个连通分量的值后,可以通过异或一个掩码((msk))调整整个连通分量的值。
  • 对于每个位 (k)(0 到 29,因 Zi≤109<230):
    • 统计连通分量中第 (k) 位为 1 的节点数。
    • 如果超过一半的节点该位为 1,则翻转该位(异或 1<<k),使更多值为 0。

这样保证总和最小。
步骤 4:输出结果
如果所有连通分量一致,输出最终序列 (A)
否则,输出 −1-1-1

示例说明
输入:

5 8
4 2 4
2 3 11
3 4 15
4 5 6
3 2 11
3 3 0
3 1 9
3 4 15

分析:
DFS:
A3=0
A1=0⊕9=9
A2=0⊕11=11
A4=0⊕15=15
A5=15⊕6=9
验证其他约束,一致。

最小化:初始 A=(9,11,0,15,9),和为 44,
根据异或性质设置掩码

对掩码异或调整后得 A=(0,2,9,6,0)和为17。
完整代码

#include<iostream>
#include<vector>
#include<cassert>
#include<cstdlib>
using namespace std;
int N, M;
vector<pair<int,int>> G[2<<17];// 邻接表 
bool vis[2<<17];
vector<int> V;// 存储当前连通分量中的所有节点
int W[2<<17];// 存储序列 A 中各元素的值// u 表示当前正在访问的节点,w 表示当前节点 u 的值
void dfs(int u, int w) {vis[u] = true;V.push_back(u);W[u] = w;for (auto [v, e] : G[u]) {if (!vis[v]) dfs(v, w ^ e);// 如果相邻节点 v 已经被访问过else if (W[v] != (w ^ e)) {// 说明根据当前路径计算出的相邻节点 v 的值与之前记录的值不一致,约束条件冲突cout << -1 << endl;// 退出整个程序,因为一旦发现不一致就无需继续处理exit(0);}}
}int main() {ios::sync_with_stdio(0),cin.tie(0);cin >> N >> M;for (int i = 0; i < M; i++) {int u, v, w;// 读取每个约束条件中的两个节点编号 u 和 v 以及它们异或的结果 wcin >> u >> v >> w;u--, v--;// 在节点 u 的邻接表中添加相邻节点 v 及边的权重 w,无向图G[u].push_back({v, w});G[v].push_back({u, w});}for (int i = 0; i < N; i++) {if (!vis[i]) {V.clear();dfs(i, 0);// 用于统计当前连通分量中每个二进制位为 1 的节点数量int cnt[30] = {};for (int u : V) {// 遍历每个二进制位(从第 0 位到第 29 位)for (int k = 0; k < 30; k++) {// 如果节点 u 的第 k 位为 1if (W[u] >> k & 1) cnt[k]++;}}// 用于存储需要异或的掩码,用于调整连通分量中所有节点的值以最小化总和int msk = 0;for (int k = 0; k < 30; k++) {// 如果当前连通分量中第 k 位为 1 的节点数量超过总数的一半if (cnt[k] > V.size() - cnt[k]) {// 将第 k 位置为 1 到掩码 msk 中msk |= 1 << k;}}for (int u : V) {// 将每个节点的值异或掩码 msk,以最小化连通分量中所有节点值的总和W[u] ^= msk;}}}for (int i = 0; i < N; i++) cout << W[i]<< " ";return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/895994.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

实验1C语言开发环境使用和数据模型,运算符,表达式

实验1 代码:#include<stdio.h> int main() { printf(" 0 \n"); printf("<H>\n"); printf("I I\n");return 0; } task1 运行结果截图:实验2 代码:#include<stdio.h> int main(){ char ans1,ans2;printf("每次课前认真…

R语言NIMBLE、Stan和INLA贝叶斯平滑及条件空间模型死亡率数据分析:提升疾病风险估计准确性

全文链接:https://tecdat.cn/?p=40365 原文出处:拓端数据部落公众号 在环境流行病学研究中,理解空间数据的特性以及如何通过合适的模型分析疾病的空间分布是至关重要的。本文主要介绍了不同类型的空间数据、空间格点过程的理论,并引入了疾病映射以及对空间风险进行平滑处理…

android组件实现圆角

圆角实现步骤效果预览 要实现如图所示的圆角步骤在app/src/main/res/drawable新建样式文件如rounded.xml<?xml version="1.0" encoding="utf-8"?> <!--实现圆角边框--> <shape xmlns:android="http://schemas.android.com/apk/res/a…

Manus AI 站在巨人(大模型)肩膀上的AI助手

3月6日,注定是科技圈的不眠之夜。Manus AI已横空出世,它可不是普通的聊天机器人,而是一个真正的全能AI助手。它能够帮你从想法到落地,直接执行听起来是不是很酷?接下来,我们看几个官方的例子,带大家体验一下它到底有多强大。 想象一下,你手头有10份简历要筛选。它会像人…

计算机组成原理学习

计算机体系专业术语 (ISA)指令集体系结构 描述计算机的功能,程序员看到的计算机的抽象视图,并定义了汇编语言和编程模型,但并没有考虑计算机的实现 微体系结构 描述一种ISA的实现方式,关注计算机的内部设计 系统体系结构 包括处理器 存储器 总线外设在内的整个系统计算机系…

0-1 背包问题

问题描述: 现有4个物品,小偷的背包总容量为8,也就是只能背起总重量为8的一个或多个物品。 那么小偷以什么样的方案,可以在背包背得动的情况下,尽可能偷价值最大的物品? 这4个物品的编号、总量、价值如下图: 物品编号:1 2 3 4 物品重量:2 3 4 5 物品价值:3 4 …

工程师必看~合宙4G模组Air780EPM的开机启动及外围电路设计!

本文介绍了合宙4G模组——Air780EPM 模块开机的完整硬件设计指南,涵盖供电要求、管脚配置、电路示例及常见问题排查方法,希望能够帮助大家避免设计错误,确保模块稳定启动!常见开机电路。 这些内容是 Air780EPM 模块硬件设计的核心指南,直接关系到模块能否稳定运行。 掌握这…

快速上手!4G模组Air780EPM的供电设计以及选型推荐

本文主要介绍了如何为 Air780EPM 模块设计供电电路,涵盖 LDO、DCDC、锂电池等多种方案。 重点包括:根据设备需求选合适电源类型,选元件时注意 LDO 散热、DCDC 电感抗冲击能力,PCB 布局要缩短走线减少干扰。针对锂电池和长待机场景,还提供了充电管理和升压电路设计技巧,帮…

爬楼梯 三种算法比较

1 /*2 假设你正在爬楼梯。需要 n 阶你才能到达楼顶。3 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?4 5 示例 1:6 输入:n = 27 输出:28 解释:有两种方法可以爬到楼顶。9 1. 1 阶 + 1 阶 10 2. 2 阶 11 12 …

从零开始:4G模组Air780EPM的串口电路设计及硬件指导!

串口作为Air780EPM模块的核心通信接口,承担着设备控制、数据传输及外设交互等关键功能,在物联网终端、智能设备、工业自动化等场景中不可或缺。 一、概述 串口作为 Air780EPM 模块最最主要的通信接口,承担着控制,数据传输,外设通信等重要功能。基本上绝大部分的 Cat.1 应用…

实验1C语言开发环境使用和数据类型,运算符,表达式

实验1 task1.c 代码:#include <stdio.h> #include <stdlib.h> int main() {printf(" O \n");printf("<H>\n");printf(" I \n");printf(" O \n");printf("<H>\n");printf(" I \n");syste…

python44页图

红色五角星 from turtle import * fillcolor("red") begin_fill() while True:forward(200)right(144)if abs(pos())<1:break end_fill() 太阳花 from turtle import* color(red,yello) begin_fill() while True:forward(200)left(170)if abs(pos())<1:break e…