【学习笔记】CF1610F Mashtali: a Space Oddysey

感觉智商还是不太够😅

正常人的做法:答案上界是显然的,就是 ∑ w \sum w w为奇数的点的个数,因为限制很松。但是直接构造比较棘手,考虑两条边 ( x , v ) (x,v) (x,v) ( v , y ) (v,y) (v,y),如果这两条边的权值也相同,那么可以在原图中将 ( x , v ) (x,v) (x,v) ( v , y ) (v,y) (v,y)删掉,然后加入 ( x , y ) (x,y) (x,y)这条边。这样每次操作后,边的数目会减少 1 1 1。一直这样操作下去,最后每个点的度数不会超过 2 2 2,因此是若干环和链,显然从链的端点或者环上任意一点开始定向即可。

具体实现方式是:枚举 x x x以及出边 v v v,然后再找到 v v v的一条出边 y y y,将 ( x , v ) (x,v) (x,v) ( v , y ) (v,y) (v,y)删掉,加入边 ( x , y ) (x,y) (x,y),然后 v v v赋值成 y y y,继续寻找 y y y的出边。写代码的时候要先把 ( x , v ) (x,v) (x,v)这条边删掉,直到 x x x的所有出边都扩展完了过后再加回来。最后还原方案只需建立二叉树然后从根节点开始遍历即可(和 kruskal \text{kruskal} kruskal重构树比较类似)。

复杂度 O ( n + m ) O(n+m) O(n+m)。但是比较难写,估计要调半天。

聪明人的做法:考虑欧拉回路。本质上就是利用了回路上出边和入边数目相同来构造,但是这道题的建图方式比较难。

考虑建立 2 n + 1 2n+1 2n+1个点(因为 1 1 1 2 2 2其实本质上是对称的,所以把点复制一遍),建边方式如下:

1.1 1.1 1.1 对于边权为 1 1 1的边 ( u , v ) (u,v) (u,v),加入边 ( u , v ) (u,v) (u,v)
1.2 1.2 1.2 对于边权为 2 2 2的边 ( u , v ) (u,v) (u,v),加入边 ( u + n , v + n ) (u+n,v+n) (u+n,v+n)
1.3 1.3 1.3 d i ( j ) d_i(j) di(j)表示 j j j连了多少条度为 i i i的边,如果 d 1 ( u ) d_1(u) d1(u) d 2 ( u ) d_2(u) d2(u)都为奇数,加入边 ( u , u + n ) (u,u+n) (u,u+n);如果只有 d 1 ( u ) d_1(u) d1(u)为奇数,加入边 ( u , 2 n + 1 ) (u,2n+1) (u,2n+1);如果只有 d 2 ( u ) d_2(u) d2(u)为奇数,加入边 ( u + n , 2 n + 1 ) (u+n,2n+1) (u+n,2n+1)

跑欧拉回路,然后根据前两类边的方向就可以确定原图中边的方向。

代码很简单。但是确实比较难想到😅

我是小丑,所以写了第一种做法。

#include<bits/stdc++.h>
#define ll long long
#define fi first
#define se second
#define pb push_back
using namespace std;
const int N=6e5+5;
int n,m,ok[N],vs[N],vs2[N],U[N],V[N],W[N],du[N],du2[N],cnt,tot;
pair<int,int>ans[N];
vector<int>s[N][2];
vector<int>vec;
vector<int>G[N];
vector<int>G2[N];
int get(int x,int y){if(y==U[x])return V[x];return U[x];
}
void dfs(int i,int pre,int j){while(s[i][j].size()&&vs[s[i][j].back()]){s[i][j].pop_back();}if(s[i][j].size()==0){vec.pb(pre);return;}int t=s[i][j].back();vs[t]=1,s[i][j].pop_back();cnt++,U[cnt]=get(pre,i),V[cnt]=get(t,i),vs[cnt]=1;G[cnt].pb(t),G[cnt].pb(pre),du2[t]++,du2[pre]++;dfs(V[cnt],cnt,j);
}
void dfs2(int u){while(G2[u].size()&&vs2[G2[u].back()])G2[u].pop_back();if(G2[u].size()==0)return;int t=G2[u].back();G2[u].pop_back();vs2[t]=1,ans[t]={u,get(t,u)},dfs2(get(t,u));
}
void dfs3(int u){if(G[u].size()){int l=G[u][0],r=G[u][1];if(V[l]==U[r]){ans[l]={U[l],V[l]},ans[r]={U[r],V[r]};}else if(U[l]==U[r]){ans[l]={V[l],U[l]},ans[r]={U[r],V[r]};}else if(V[l]==V[r]){ans[l]={U[l],V[l]},ans[r]={V[r],U[r]};}else{ans[l]={V[l],U[l]},ans[r]={V[r],U[r]};}if(ans[l].fi!=ans[u].fi){swap(ans[l].fi,ans[l].se);swap(ans[r].fi,ans[r].se);}dfs3(l),dfs3(r);}
}
int main(){ios::sync_with_stdio(false);cin.tie(0),cout.tie(0);cin>>n>>m,cnt=m;for(int i=1;i<=m;i++){int u,v,w;cin>>u>>v>>w,w--;s[u][w].pb(i),s[v][w].pb(i);if(w==0)ok[u]^=1,ok[v]^=1;U[i]=u,V[i]=v,W[i]=w;}for(int i=1;i<=n;i++){for(int j=0;j<2;j++){while(1){while(s[i][j].size()&&vs[s[i][j].back()])s[i][j].pop_back();if(s[i][j].size()==0)break;int t=s[i][j].back();s[i][j].pop_back();vs[t]=1,dfs(get(t,i),t,j);}while(vec.size()){int t=vec.back();vec.pop_back();vs[t]=0,s[U[t]][j].pb(t),s[V[t]][j].pb(t);}}}for(int i=1;i<=n;i++){for(int j=0;j<2;j++){while(1){while(s[i][j].size()&&vs[s[i][j].back()])s[i][j].pop_back();if(s[i][j].size()==0)break;int t=s[i][j].back();s[i][j].pop_back();vs[t]=1;int k=get(t,i);du[i]++,du[k]++,G2[i].pb(t),G2[k].pb(t);}}}for(int i=1;i<=n;i++)if(du[i]==1)dfs2(i);for(int i=1;i<=n;i++)dfs2(i);for(int i=1;i<=cnt;i++)if(du2[i]==0)dfs3(i);for(int i=1;i<=n;i++)tot+=ok[i];cout<<tot<<"\n";for(int i=1;i<=m;i++){if(ans[i].fi==U[i])cout<<1;else cout<<2;}
}

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

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

相关文章

互联网Java工程师面试题·Memcached 篇·第二弹

目录 10、memcached 如何实现冗余机制&#xff1f; 11、memcached 如何处理容错的&#xff1f; 12、如何将 memcached 中 item 批量导入导出&#xff1f; 13、如果缓存数据在导出导入之间过期了&#xff0c;您又怎么处理这些数据呢&#xff1f; 14、memcached 是如何做身份…

前(jsencrypt)后(node-rsa/crypto)端 RSA 加密与解密

前端使用 jsencrypt 进行加密&#xff0c;服务端使用 node-rsa 或 crypto 进行解密。 jsencrypt 加密 需要注意的是 RSA 加密的数据长度是有限制的&#xff0c;过长的数据可能导致解密失败。允许的数据长度与密钥长度成正比。 import JSEncrypt from jsencrypt;// 通过 node…

数据源报表

1.新建报表 2.新建数据集 3.维护数据源 支持的数据库还是蛮多哈 4.选择数据源表 5.编写sql 编码&#xff1a;SQL数据集的标识 注&#xff1a;避免特殊字符和_名称&#xff1a;SQL数据集的名称是否集合&#xff1a;否为单数据&#xff1b;是为多数据列表&#xff0c;如果多条数据…

一文掌握Linux系统信息查看命令(CPU、内存、进程、网口、磁盘、硬件)

引言 大家好&#xff0c;欢迎来到我的技术博客&#xff01;如果你是一名Linux系统管理员、开发者或者热衷于学习Linux系统的用户&#xff0c;那么你一定需要掌握查看系统信息的命令。在这篇博客中&#xff0c;我将为你介绍一些常用的Linux命令&#xff0c;帮助你快速了解和监控…

【Linux学习】05-2Linux上部署项目

Linux&#xff08;B站黑马&#xff09;学习笔记 01Linux初识与安装 02Linux基础命令 03Linux用户和权限 04Linux实用操作 05-1Linux上安装部署各类软件 05-2Linux上部署项目 文章目录 Linux&#xff08;B站黑马&#xff09;学习笔记前言05-2Linux上部署项目部署Springboot项目…

数据结构 2.2 单循环链表

2.单循环链表 data|next——>data|next——>data|next——>头节点 1.初始化链表 2.增加节点&#xff08;头插法、尾插法&#xff09; 3.删除节点 4.遍历链表 定义一个结构体&#xff0c;存放data域和指针域&#xff1a; typedef struct Node {//定义一个结构体&…

特斯拉被称为自动驾驶领域的苹果

特斯拉的自动驾驶技术无疑是居于世界上领先地位的,有人形容特斯拉是自动驾驶汽车领域的苹果。特斯拉发布的Tesla Vision系统只配备了摄像头,不依靠雷达。 这并不是特斯拉唯一和其它对手不同的地方,他们的整个战略都是基于车队和销售产品,而其大多数竞争对手则销售自…

Python数据攻略-SQL和Mongodb的CRUD方法汇总

数据仓库是现代企业和个人项目中不可或缺的一部分。它们不仅存储了大量的数据,而且提供了查询和更新这些数据的方法。在本文中将探讨两种流行的数据仓库类型:SQL(例如MySQL,PostgreSQL,SQLite)和NoSQL(特别是MongoDB)。 本文为数据分析师和数据工程师,尤其是那些刚入…

输入一个大写字母,程序根据输入字符在字母表的顺序位置n,输出一个高度为n的金字塔图形

python字母金字塔根据输入的字母输出一个字母金字塔输入一个大写字母&#xff0c;程序根据输入字符在字母表的顺序位置n,输出一个高度为n的金字塔图形&#xff0c;比如输入E时&#xff0c;此时 字母金字塔 # A # ABA # ABCBA # ABCDCBA # ABCDEDCBA 看到问…

DPDK系列之三十三DPDK并行机制的底层支持

一、背景介绍 在前面介绍了DPDK中的上层对并行的支持&#xff0c;特别是对多核的支持。但是&#xff0c;大家都知道&#xff0c;再怎么好的设计和架构&#xff0c;再优秀的编码&#xff0c;最终都要落到硬件和固件对整个上层应用的支持。单纯的硬件好处理&#xff0c;一个核不…

防抖和节流的实现

防抖和节流的实现 什么是防抖和节流实现防抖和节流防抖节流 防抖和节流的应用场景 什么是防抖和节流 防抖和节流是前端开发中常用的两种性能优化技术。 为什么需要防抖和节流呢&#xff1f; 两者目的都是为了防止某个时间段内操作频繁触发&#xff0c;造成性能消耗。 防抖&…

NAT+ACL+mstp小综合

三、实验一相关知识点 1&#xff0c;实验&#xff1a;NAT 综合实验 2&#xff0c;拓扑&#xff1a; 3&#xff0c;需求: 1&#xff09;&#xff0c;实现VLAN20 的除了20这台主机以外所有主机上网访问外网 2&#xff09;&#xff0c;实现VLAN30 的主机为奇数电脑上网 3&#…

XV6 操作系统实验

环境搭建 ubuntu 新建一个文件setup.sh&#xff0c;内容如下 #获取工具链 git clone --recursive https://github.com/riscv/riscv-gnu-toolchain #安装必要依赖 sudo apt-get update sudo apt-get install autoconf automake autotools-dev curl libmpc-dev libmpfr-dev li…

如何使用 Hotshot 通过文字生成 GIF 动画

Hotshot 是一个基于人工智能的工具&#xff0c;可用于通过文字生成 GIF 动画。该工具使用最新的图像生成技术来创建逼真的动画&#xff0c;即使是复杂的文字描述也能做到。 hotshot访问地址 使用 Hotshot 生成 GIF 动画 要使用 Hotshot 生成 GIF 动画&#xff0c;您需要首先…

FreeRTOS入门教程(队列详细使用示例)

文章目录 前言一、队列基本使用二、如何分辨数据源三、传输大块数据总结 前言 上篇文章我们已经讲解了队列的概念和队列相关的API函数&#xff0c;那么本篇文章的话就开始带大家来学习使用队列。 一、队列基本使用 这个例子将会创建三个任务&#xff0c;其中两个任务用来发送…

vue.js 生命周期

在页面首次加载执行顺序有如下&#xff1a; beforeCreate //在实例初始化之后、创建之前执行created //实例创建后执行beforeMounted //在挂载开始之前调用filters //挂载前加载过滤器computed //计算属性directives-bind //只调用一次&#xff0c;在指令第一次绑定到元素时调…

Leetcode 151. 反转字符串中的单词 JS版两种方法(内置API,双指针)有详细讲解 小白放心食用

&#x1f3b6;Leetcode 151. 反转字符串中的单词 难度&#xff1a;中等 ✨题目描述&#xff1a; 给你一个字符串 s &#xff0c;请你反转字符串中 单词 的顺序。 单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。 返回 单词 顺序颠倒且 …

吃鸡高手亲授:玩转绝地求生,分享顶级游戏干货!

绝地求生&#xff08;PUBG&#xff09;自上线以来&#xff0c;成为了全球热门游戏。作为吃鸡行家&#xff0c;我将分享一些独家技巧和干货&#xff0c;帮助您提高游戏战斗力&#xff0c;享受顶级游戏作战体验&#xff01; 首先&#xff0c;让我们谈一谈战斗力升级。想要在吃鸡游…

zabbix监控

目录 一、zabbix概述 1.zabbix是什么? 二、zabbix主要功能&#xff1a; 三.zabbix监控原理 四、zabbix监控对象&#xff08;常用的监控程序&#xff09; 五、zabbix监控模式&#xff1a; 六、zabbix监控架构 七、部署zabbix 一、zabbix概述 1.zabbix是什么? zabbix是一…

TI单芯片毫米波雷达代码走读(二十七)—— 角度维(3D)处理之通道间幅相一致性补偿

TI单芯片毫米波雷达1642代码走读(〇)——总纲 书接上回,我们知晓了3D处理的主要流程,相信大家都已理解基本的原理。在正式进行数据分析之前还有一步关键的步骤需要说明,即通道间的幅相一致性补偿问题。 细心的朋友可能注意到,在3D处理的的原码中有两个函数我一直没有讲:…