HDU6311 Cover

题意:

给出\(N\)个点的简单无向图,不一定联通,现在要用最少的路径去覆盖所有边,并且每条边只被覆盖一次,问最少路径覆盖数和各条路径

\(N\le 10^5\)

题解:

对于每个连通块分别处理

考虑每个联通块,必然是用最少的欧拉路径去覆盖,首先考虑连通块里没有奇数度数的点的情况,这个情况下只要跑欧拉回路即可

如果连通块中有\(x\)个奇数度数的点,那么显然\(2|x\),且必然是用\(\frac{x}{2}\)条欧拉路径去覆盖,每两个奇数度数的顶点之间会有一条欧拉路径,考虑如何构造路径,首先将奇数度数的顶点两两配对连边,只剩下一对奇数度数点不连边,然后在新建的图中跑欧拉路径(此时必然存在欧拉路径),可以发现其中\(\frac{x}{2}-1\)条新加入的边正好把路径分成了\(\frac{x}{2}\)条,这些分开来的路径正好是所求路径

view code
//#pragma GCC optimize("O3")
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<bits/stdc++.h>
using namespace std;
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
int n, m, deg[MAXN], bel[MAXN], vis[MAXN<<2], num[MAXN];
vector<int> pt[MAXN];
struct Graph{
int head[MAXN],to[MAXN<<2],nxt[MAXN<<2],tot,id[MAXN<<2];
void clear(){ tot = 0; memset(head,255,MAXN<<2); }
void addEdge(int u, int v, int idd){
to[tot] = v; nxt[tot] = head[u]; id[tot] = idd;
vis[tot] = false; head[u] = tot++;
to[tot] = u; nxt[tot] = head[v]; id[tot] = -idd;
vis[tot] = false; head[v] = tot++;
}
}G;
void mark(int u, int id){
bel[u] = id;
pt[id].push_back(u);
for(int i = G.head[u]; ~i; i = G.nxt[i]){
int v = G.to[i];
if(!bel[v]) mark(v,id);
}
}
stack<int> stk;
void euler(int u){
int now = ++num[u];
for(int i = G.head[u]; ~i; i = G.nxt[i]){
if(vis[i]) continue;
G.head[u] = G.nxt[i];
vis[i] = vis[i^1] = true;
euler(G.to[i]);
stk.push(G.id[i]);
if(now!=num[u]) break;
}
}
void print(){
printf("%d ",stk.size());
while(!stk.empty()){
printf("%d%c",stk.top()," \n"[stk.size()==1]);
stk.pop();
}
}
void rua(int id){
int odddeg = 0;
for(int &x : pt[id]) if(deg[x]&1) odddeg++;
if(!odddeg){
euler(pt[id][0]);
print();
}
else{
int last = -1;
for(int &x : pt[id]){
if(odddeg==2) break;
if(deg[x]&1){
if(last==-1) last = x;
else{
G.addEdge(last,x,0);
deg[last]++; deg[x]++;
last = -1;
odddeg -= 2;
}
}
}
for(int &x : pt[id]) if(deg[x]&1) last = x;
euler(last);
vector<int> vec;
while(true){
vec.clear();
while(!stk.empty() and stk.top()!=0){
vec.push_back(stk.top());
stk.pop();
}
if(!stk.empty()) stk.pop();
printf("%d",vec.size());
for(int x : vec) printf(" %d",x);
puts("");
if(stk.empty()) break;
}
}
}
void solve(){
G.clear();
memset(deg+1,0,n<<2);
for(int i = 1; i <= m; i++){
int u, v; scanf("%d %d",&u,&v);
G.addEdge(u,v,i);
deg[u]++, deg[v]++;
}
int ID = 0;
memset(bel+1,0,n<<2);
int __count = 0;
for(int i = 1; i <= n; i++) if(!bel[i]){
pt[++ID].clear();
mark(i,ID);
if(pt[ID].size() > 1){
int odddeg = 0;
for(int x : pt[ID]) if(deg[x]&1) odddeg++;
if(!odddeg) __count++;
else __count += odddeg / 2;
}
}
printf("%d\n",__count);
for(int i = 1; i <= ID; i++){
if(pt[i].size() == 1) continue;
rua(i);
}
}
int main(){
while(scanf("%d %d",&n,&m)!=EOF) solve();
return 0;
}

HDU6311 Cover【欧拉路径 | 回路】的更多相关文章

  1. HDU6311 Cover (欧拉路径->无向图有最少用多少条边不重复的路径可以覆盖一个张无向图)

    题意:有最少用多少条边不重复的路径可以覆盖一个张无向图 ,输出每条路径的边的序号 , 如果是反向就输出-id. 也就是可以多少次一笔画的方式画完这个无向图. 题解:我们已知最优胜的情况是整个图是欧拉图 ...

  2. hdu6311 Cover (欧拉路径输出)

    hdu6311Cover 题目传送门 题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径. ...

  3. PKU 2513 Colored Sticks(并查集+Trie树+欧拉路径(回路))

    题目大意: 给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相连接的一端必须是同颜色的. 解题思路: 可以用图论中欧拉路的知识来解这道题,首先可以把木棒两端看成节点 ...

  4. HDU 1116 Play on Words(欧拉路径(回路))

    http://acm.hdu.edu.cn/showproblem.php?pid=1116 题意:判断n个单词是否可以相连成一条链或一个环,两个单词可以相连的条件是 前一个单词的最后一个字母和后一个 ...

  5. HDU - 6311 Cover (欧拉路径)

    题意:有最少用多少条边不重复的路径可以覆盖一个张无向图. 分析:对于一个连通块(单个点除外),如果奇度数点个数为 k,那么至少需要max{k/2,1}  条路径.将奇度数的点两两相连边(虚边),然后先 ...

  6. 欧拉回路 & 欧拉路径

    欧拉路径 & 欧拉回路 概念 欧拉路径: 如果图 G 种的一条路径包括所有的边,且仅通过一次的路径. 欧拉回路: 能回到起点的欧拉路径. 混合图: 既有无向边又有无向边的图. 判定 无向图 一 ...

  7. P1341 无序字母对【欧拉路径】- Hierholzer模板

    P1341 无序字母对 提交 24.87k 通过 6.80k 时间限制 1.00s 内存限制 125.00MB 题目提供者yeszy 难度提高+/省选- 历史分数100 提交记录 查看题解 标签 福建 ...

  8. qbxt Day 5 图论一些基础知识

    就是一些感觉比较容易忘的知识 假设根为第0层, 在二叉树的i层上至多有2i个结点,整颗二叉树(深度为k)最多有\(2^{k+1}-1\)个节点 对于任何一棵非空二叉树,如果叶结点个数为\(n_0\), ...

  9. Day 4 -E - Catenyms POJ - 2337

    A catenym is a pair of words separated by a period such that the last letter of the first word is th ...

随机推荐

  1. Docusaurus2 快速建站,发布 GitHub Pages

    Docusaurus2 可快速搭建文档.博客.官网等网站,并发布到 GitHub Pages, Serverless 等. 我们只需 Markdown 写写内容就行,也可直接编写 React 组件嵌入 ...

  2. 【SpringBoot1.x】SpringBoot1.x 分布式

    SpringBoot1.x 分布式 分布式应用 Zookeeper&Dubbo ZooKeeper 是用于分布式应用程序的高性能协调服务.它在一个简单的界面中公开了常见的服务,例如命名,配置管 ...

  3. Java并发编程实战(5)- 线程生命周期

    在这篇文章中,我们来聊一下线程的生命周期. 目录 概述 操作系统中的线程生命周期 Java中的线程生命周期 Java线程状态转换 运行状态和阻塞状态之间的转换 运行状态和无时限等待状态的切换 运行状态 ...

  4. 【Java】面向对象

    重新搞一波 复习巩固 简单记录 慕课网 imooc Java 零基础入门-Java面向对象-面向对象 都是视频课件里的. 文章目录 面向对象 什么是对象 什么是面向对象 类 什么是对象的属性和方法 类 ...

  5. 【ASM】asm中添加 diskgroup

    环境:rhel5 Oracle10g rac 背景:在esxi中添加了一个20g的共享磁盘准备存放归档日志用 一.准备环境 1.添加共享磁盘并且格式化 #fdisk -l查看磁盘已经添加完成 #fdi ...

  6. ABAP 面试问题和答案

    What is an ABAP data dictionary?- ABAP 4 data dictionary describes the logical structures of the obj ...

  7. 全球城市ZoneId和UTC时间偏移量的最全对照表

    前言 你好,我是A哥(YourBatman). 如你所知,现行的世界标准时间是UTC世界协调时,时区已不直接参与时间计算.但是呢,城市名称or时区是人们所能记忆和容易沟通的名词,因此我们迫切需要一个对 ...

  8. SourceGenerator入门指北

    SourceGenerator介绍 SourceGenerator于2020年4月29日在微软的.net blog首次介绍,大概说的是开发者编可以写分析器,在项目代码编译时,分析器分析项目既有的静态代 ...

  9. centos 7.0 ping百度提示:ping: www.baidu.com: Name or service not known

    解决方法一: 添加dns服务器 vi /etc/resolv.conf 在文件中添加如下两行: nameserver 8.8.8.8 nameserver 8.8.4.4 保存退出,重启服务器.之后再 ...

  10. LVS负载均衡理论以及算法概要

    一. LVS简介 LVS是Linux Virtual Server的简称,也就是Linux虚拟服务器, 由章文嵩博士发起的自由软件项目,它的官方站点是www.linuxvirtualserver.or ...