link。

断环后把断的边所连的两个点特殊标记,作为两个特殊点。这样就是一个树,树的做法很简单吧,把两个特殊点特殊处理带进状态即可。

具体一点就是,设 \(f(x,c_x,c_f,c_{rt_1},c_{rt_2})\) 表示处理到 \(x\) 点,\(x\) / \(x\) 的前驱 / 特殊点 1 / 特殊点 2 是否染色,转移很基础,具体看代码(代码中写的是状压)。

注意判无解……

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define cmin(x, y) x = min(x, y)
#define cmax(x, y) x = max(x, y)
template<typename T=int> inline T read() {
T x=0; char c=getchar(); bool f=0;
while(c<'0' || c>'9') f|=c=='-',c=getchar();
while(c>='0' && c<='9') x=x*10+(c&15),c=getchar();
return f?-x:x;
}
__attribute__((target("avx"), optimize("O3", "unroll-loops")))
const int INF=1e9+7;
int n,fa[100100],rt,exrt,dp[100100][17];
vector<int> e[100100];
int makeSta(vector<int> v) {
int res=0; assert(v.size()==4u);
for(int i=0; i<4; ++i) {
res+=(1<<(3-i))*v[i];
assert(0<=v[i] && v[i]<=1);
}
return res;
}
int GetAns(const int now,const int f,const int Sta) {
// Sta: colnow(3), colf(2), colrt(1), colexrt(0)
if(~dp[now][Sta]) return dp[now][Sta];
if((now==rt && ((Sta>>3)&1)!=((Sta>>1)&1))
|| (now==exrt && (((Sta>>3)&1)!=(Sta&1))) || (now==exrt && (Sta>>2)&1 && (Sta>>1)&1)) return dp[now][Sta]=INF;
int cnt=(Sta>>3)&1,res=INF; // number of vertexes coloured
for(const int y:e[now]) if(y!=f) cnt+=GetAns(y,now,makeSta({0,(Sta>>3)&1,(Sta>>1)&1,Sta&1}));
if((Sta>>2)&1 || (now==rt && Sta&1) || (now==exrt && (Sta>>1)&1)) cmin(res,cnt);
else {
for(const int y:e[now]) if(y!=f) cmin(res,cnt-GetAns(y,now,makeSta({0,(Sta>>3)&1,(Sta>>1)&1,Sta&1}))
+GetAns(y,now,makeSta({1,(Sta>>3)&1,(Sta>>1)&1,Sta&1})));
}
return dp[now][Sta]=res;
}
int find(int now) { while(now!=fa[now]) now=fa[now]=fa[fa[now]]; return now; }
signed main() {
// freopen("logicians.in","r",stdin);
// freopen("logicians.out","w",stdout);
memset(dp,-1,sizeof dp);
n=read();
for(int i=1; i<=n; ++i) fa[i]=i;
for(int i=1,x,y; i<=n; ++i) {
x=read(),y=read();
if(find(x)!=find(y)) {
fa[find(x)]=find(y);
e[x].push_back(y);
e[y].push_back(x);
}
else rt=x,exrt=y;
}
int ret=INF;
for(const int i:{0,1}) for(const int j:{0,1}) cmin(ret,GetAns(rt,0,makeSta({i,0,i,j})));
if(ret==INF) return puts("-1"),0;
printf("%lld\n",ret);
return 0;
}

「coci 2021-2022 #1」Logičari的更多相关文章

  1. GitHub 公布 2021 Top 10 博文「GitHub 热点速览」

    作者:HelloGitHub-小鱼干 2021 年在这周彻底同我们告别了,在本周的「News 快读」模块你可以看到过去一年 GitHub 的热门文章,其中有我们熟悉的可能让很多程序员"失业& ...

  2. 灵感宝盒新增「线上云展会」产品,「直播观赏联动」等你共建丨RTE NG-Lab 双周报

    前言 哈喽各位开发者,「RTE NG-Lab 双周报」如期而至! 近两周,我们更新了一些新的实时互动场景和产品,也举办了代码实验室的第一次线下活动,与大家一起体验了声网最新的 4.0 SDK. 灵感宝 ...

  3. 众安「尊享e生」果真牛的不可一世么?

    近日,具有互联网基因的.亏损大户(成立三年基本没盈利,今年二季度末亏损近4亿,你能指望它多厉害?).财产险公司—众安推出“尊享e生”中高端医疗保险(财险公司经营中高端医疗真的很厉害?真的是中高端医疗险 ...

  4. XCActionBar 「Xcode 中的 Alfred」

    下载地址:https://github.com/pdcgomes/XCActionBar 基本命令: (1)「command+shift+8」或者双击「command」键可以打开「动作输入框窗口」 ( ...

  5. Git 执行 「fork 出来的仓库」和「最新版本的原仓库」内容同步更新

    当我们在 GitHub 上 fork 出一个仓库后,如果原仓库更新了,此时怎样才能保证我们 fork 出来的仓库和原仓库内容一致呢?我们一般关注的是仓库的 master(主干分支)的内容,通过以下步骤 ...

  6. 翻译「C++ Rvalue References Explained」C++右值引用详解 Part1:概述

    本文系对「C++ Rvalue References Explained」 该文的翻译,原文作者:Thomas Becker. 该文较详细的解释了C++11右值引用的作用和出现的意义,也同时被Scot ...

  7. 苹果搜索广告后台大揭秘,最全最细致详解,手把手设置教程「后附官方视频」-b

    WWDC2016 搜索广告分会视频和 PPT 发布了,ASO100 带开发者第一时间了解 Search Ads 后台设置(文末有原声视频). 首先介绍一下搜索广告的模式和竞价规则 广告模式为 CPT( ...

  8. 被「李笑来老师」拉黑之「JavaScript微博自动转发的脚本」

    故事的背景如下图,李笑来 老师于10月19日在 知乎Live 开设 一小时建立终生受用的阅读操作系统 的讲座,他老人家看到大家伙报名踊跃,便在微博上发起了一个 猜数量赢取iPhone7 的活动. 因为 ...

  9. iOS模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    Write in the first[写在最前] 对于从事 iOS 开发人员来说,当提到 ** runtime时,我想都可以说出来 「runtime 运行时」和基本使用的方法.相信很多开发者跟我当初一 ...

  10. iOS 模式详解—「runtime面试、工作」看我就 🐒 了 ^_^.

    引导 Copyright © PBwaterln Unauthorized shall not be *copy reprinted* . 对于从事 iOS 开发人员来说,所有的人都会答出「runti ...

随机推荐

  1. c# 如何将枚举以下拉数据源的形式返回给前端

    前言: 相信各位有碰到过与我类似的问题,当表中存一些状态的字段,无非以下几种形式1.直接写死 如: 正常:1,异常:2 ,还有一种则是写在字典中,再或者就是加在枚举上,前两者对于返回下拉数据源来说比较 ...

  2. 基于drawio构建流程图编辑器

    基于drawio构建流程图编辑器 drawio是一款非常强大的开源在线的流程图编辑器,支持绘制各种形式的图表,提供了Web端与客户端支持,同时也支持多种资源类型的导出. 描述 在我们平时写论文.文档时 ...

  3. rabbitmq安装部署和常用命令

    python操作rabbitmq rabbitmq实现可以使用java或者springboot的封装方法,自己创建实现,也可以使用中间件实现,相对于自建,使用rabbitmq应用场景及使用更系统安全. ...

  4. 用写代码的方式画图-试下PlantUML吧

    1 序言 所谓一图胜千言,大家平日在工作中编写文档时,往往都需要画各种图来表达中心思想,比如流程图.时序图.UML 图,很多人选择使用 Axure .PrecessOn.Diagrams(darw.i ...

  5. 动态SQL与静态SQL使用场景

    静态SQL 和动态SQL 的区别 静态SQL(或嵌入式SQL) 是应用程序中的 SQL 语句,它们在运行时不会更改,因此可以硬编码到应用程序中. 动态 SQL是在运行时构造的 SQL 语句:例如,应用 ...

  6. centos系统给centos-root硬盘扩容

    此服务器为虚拟机,通过lsblk命令查看当前虚拟机硬盘: 其中一块硬盘大小为100G,已作为系统盘使用,但是只分配了15G的空间使用,需要对剩余空间进行分区,并扩容到对应centos卷组的root目录 ...

  7. C语言循环坑 -- continue的坑

    文章目录 前言 一.continue语法 1.continue的作用 2.语法 二.大坑项目 题目 分析 正确写法 三.进坑调试 第一种 第二种 总结 前言 在使用continue和break时,会出 ...

  8. locust与jmeter测试过程及结果对比

    JMeter和Locust都是强大的性能测试工具,各自拥有自己的优势和专注领域.JMeter提供了全面的功能和基于GUI的界面,适用于复杂的场景和非技术人员.相比之下,Locust采用了以代码为中心的 ...

  9. iptables防火墙调试,想打印个日志就这么难

    背景 怎么会讲这个话题,这个说来真的长了.但是,长话短说,也是可以的. 我前面的文章提到,线上的服务用了c3p0数据库连接池,会偶发连接泄露问题,而分析到最后,又怀疑是db侧主动关闭连接,或者是服务所 ...

  10. docker 镜像与容器存储目录结构

    目录列表及大小示例-20220314 root@dewan01:/var/lib/docker# du -sh * 88K buildkit 72K containers 884K image 60K ...