@bzoj - 3724@ PA2014Final Krolestwo
@description@
你有一个无向连通图,边的总数为偶数。
设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除)。对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的路径将u和v连接。每条路径允许经过重复的点,但不允许经过重复的边。这k/2条路径之间也不能有重复的边。
@solution@
先不考虑路径长度必须为偶数,其实就是跑 k/2 条欧拉路径。
这个实现方法很多,讲一种这道题可以用的:建虚点 s,s 向所有奇点连虚边,跑欧拉回路,然后断开所有虚边。
考虑路径长度为偶数,联想到二分图。考虑一个点拆成黑白两点,原来的一条边 (u, v) 对应了 u 的黑/白点连向 v 的白/黑点。
如果虚点 s 只向奇点的黑点连边,则跑出来的欧拉回路一定是路径长度为偶数。
不过这个拆点中,一条边 (u, v) 只能对应 u 的黑/白点连向 v 的白/黑点中一种情况。
所以我们要加以选择,使得建出来的新图中每个点的度数依然为偶数。
因为白点度数 + 黑点度数 = 原图点度数,所以我们只需要白点度数为偶数即可。
考虑将问题转化一下:给每条边 (u, v) 定向成 u -> v 或 v -> u,定向后每个点的出边即这个点白点连出去的边。
这个问题就是经典问题了,建出任意一棵生成树(一般选 dfs 树)后,非树边随便选,树边自下而上调整,即可保证每个白点的度数为偶数。
@accepted code@
#include <cstdio>
const int MAXN = 2*250000;
struct Graph{
struct edge{
int to, id; bool tag;
edge *nxt, *rev;
}edges[2*MAXN + 5], *adj[MAXN + 5], *ecnt;
Graph() {ecnt = edges;}
void addedge(int u, int v, int i) {
edge *p = (++ecnt), *q = (++ecnt);
p->to = v, p->id = i, p->nxt = adj[u], adj[u] = p;
q->to = u, q->id = i, q->nxt = adj[v], adj[v] = q;
p->rev = q, q->rev = p;
// printf("! %d %d %d\n", u, v, i);
}
}G1, G2;
#define rep(G, x) for(Graph::edge *p=G.adj[x];p;p=p->nxt)
int dfn[MAXN + 5], oud[MAXN + 5], dcnt;
void dfs(int x, int f) {
dfn[x] = (++dcnt);
rep(G1, x) {
if( p->to == f ) continue;
if( dfn[p->to] ) {
if( dfn[p->to] < dfn[x] )
G2.addedge(2*x, 2*p->to-1, p->id), oud[x]++;
}
else {
dfs(p->to, x);
if( oud[p->to] & 1 )
G2.addedge(2*p->to, 2*x-1, p->id), oud[p->to]++;
else G2.addedge(2*p->to-1, 2*x, p->id), oud[x]++;
}
}
}
Graph::edge *stk[MAXN + 5]; int tp;
void dfs2(int x) {
// printf("! %d\n", x);
for(;G2.adj[x];) {
Graph::edge *p = G2.adj[x]; G2.adj[x] = G2.adj[x]->nxt;
if( p->tag ) continue;
p->tag = p->rev->tag = true;
dfs2(p->to);
stk[++tp] = p->rev;
}
}
int deg[MAXN + 5];
int main() {
int n, m; scanf("%d%d", &n, &m);
for(int i=1;i<=m;i++) {
int a, b; scanf("%d%d", &a, &b);
G1.addedge(a, b, i), deg[a]++, deg[b]++;
}
for(int i=1;i<=n;i++)
if( deg[i] & 1 ) G2.addedge(0, 2*i-1, -1);
dfs(1, -1), dfs2(0);
int lst = 1;
/*
for(int i=1;i<=tp;i++)
printf("%d ", stk[i]->id);
puts("");
*/
for(int i=2;i<=tp;i++) {
if( stk[i]->id == -1 ) {
printf("%d %d %d\n", (stk[lst]->to + 1)/2, (stk[i]->rev->to + 1)/2, i - lst - 1);
for(int j=lst+1;j<=i-1;j++) {
printf("%d%c", stk[j]->id, j + 1 == i ? '\n' : ' ');
}
i++, lst = i;
}
}
}
@details@
需要注意欧拉回路的实现,要用类当前弧优化的方法进行优化,不然时间复杂度不正确。
@bzoj - 3724@ PA2014Final Krolestwo的更多相关文章
- 【刷题】BZOJ 3724 PA2014Final Krolestwo
Description 你有一个无向连通图,边的总数为偶数. 设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每 ...
- bzoj 3728: PA2014Final Zarowki
3728: PA2014Final Zarowki Description 有n个房间和n盏灯,你需要在每个房间里放入一盏灯.每盏灯都有一定功率,每间房间都需要不少于一定功率的灯泡才可以完全照亮.你可 ...
- BZOJ3724 PA2014Final Krolestwo(欧拉回路+构造)
如果没有长度为偶数的限制,新建一个点向所有奇点连边,跑欧拉回路即可,显然此时一定存在欧拉回路,因为所有点度数都为偶数. 考虑长度为偶数的限制,将每个点拆成两个点放进一个二分图里,那么每条原图中的边在二 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- BZOJ 2127: happiness [最小割]
2127: happiness Time Limit: 51 Sec Memory Limit: 259 MBSubmit: 1815 Solved: 878[Submit][Status][Di ...
- BZOJ 3275: Number
3275: Number Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 874 Solved: 371[Submit][Status][Discus ...
- BZOJ 2879: [Noi2012]美食节
2879: [Noi2012]美食节 Time Limit: 10 Sec Memory Limit: 512 MBSubmit: 1834 Solved: 969[Submit][Status] ...
- bzoj 4610 Ceiling Functi
bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...
- BZOJ 题目整理
bzoj 500题纪念 总结一发题目吧,挑几道题整理一下,(方便拖板子) 1039:每条线段与前一条线段之间的长度的比例和夹角不会因平移.旋转.放缩而改变,所以将每条轨迹改为比例和夹角的序列,复制一份 ...
随机推荐
- ORM多表增删改查
一 创建多表 在models.py里创建4张表:Author(作者).AuthorDetail(作者详细信息).Publish(出版社).Book(书) 四张表关系为: (1)首先创建一对一关系.On ...
- Alink漫谈(四) : 模型的来龙去脉
Alink漫谈(四) : 模型的来龙去脉 目录 Alink漫谈(四) : 模型的来龙去脉 0x00 摘要 0x01 模型 1.1 模型包含内容 1.2 Alink的模型文件 0x02 流程图 0x03 ...
- 为什么Tableviewcell创建时可以不判空
dequeueReuseableCellWithIdentifier:与dequeueReuseableCellWithIdentifier:forIndexPath:的区别: 前者不必向tableV ...
- SXSSFWorkbook的简单使用
在工作中使用到SXSSFWorkbook来导出Excel,写一篇博客记录一下SXSSFWorkbook的使用方法 1.介绍 SXSSFWorkbook是属于apache基金会的Excel导出工具类,从 ...
- 人机协同与AI能力训练
我们进行<中台战略>一书的第三期分享. “人机融合是解决aI机器人冷启动的绝佳解决方案,我们这里引入了一个应答满意度的指标,每一个咨询应答都对应一个应答满意度.当消费者应该回答选择转入人工 ...
- 【java】关键字volatile
volatile 1. 含义: volatile是JVM提供的轻量级的同步机制,具有三个特点:保证可见性.不保证原子性.禁止指令重排. 1.1 保证可见性 一个线程修改了共享变量并写回主内存,其他线程 ...
- Linux(一):VMware安装出现的问题
目录 1 兼容性问题 2 VMware打卡虚拟机提示"此虚拟机可能已被复制或移动" 1 兼容性问题 问题:VMware Workstation 与 Device/Credentia ...
- 关于Backus-Naur Form巴克斯诺尔范式和扩展巴克斯范式的知识点和相关词语中英文对照
巴克斯诺尔范式的相关词语中英文对照和知识点 syntax 语法 强调的是编程语言的组形式,例如一个句子中会包含表达式.陈述还有各种单元等等 semantics 语义 强调的是这个编程语言的实际含义,例 ...
- Chisel3 - 模块
https://mp.weixin.qq.com/s/2vjM-gcauvHnn6KJzlOm4g Chisel的模块和Verilog的模块很相似,都用来定义模块结构(hierarchical s ...
- Linux磁盘与文件系统管理概要
Linux磁盘与文件系统管理 硬盘组成与分区 硬盘组成 圆形的盘片(主要记录数据) 机械手臂与磁头(可读取盘片上的数据) 主轴马达,转动盘片,让机械手臂的磁头在盘片上读取数据 扇区(Sector)为最 ...