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. 真的,kafka 入门看这一篇准没错!

    什么是 Kafka Kafka 是一个分布式流式平台,它有三个关键能力 订阅发布记录流,它类似于企业中的消息队列 或 企业消息传递系统 以容错的方式存储记录流 实时记录流 Kafka 的应用 作为消息 ...

  2. java8新特性之stream流

    Stream 流是 Java 8 提供给开发者一套新的处理集合的API,他把我们将要处理的集合作为流,就像流水线一样,我们可以对其中的元素进行筛选,过滤,排序等中间操作,只不过这种操作更加简洁高效. ...

  3. kubernetes环境部署单节点redis

    kubernetes部署redis数据库(单节点) redis简介 Redis 是我们常用的非关系型数据库,在项目开发.测试.部署到生成环境时,经常需要部署一套 Redis 来对数据进行缓存.这里介绍 ...

  4. 【ORA】ORA-27125:unable to create shared memory segment

    在安装Oracle 10g的时候出现一个了错误,在网上总结了一下大牛写的文章 ORA-27125:unable to create shared memory segment 安装时出现这个错误安装会 ...

  5. 【Oracle】删除表空间

    删除表空间如果是 SQL> DROP TABLEPSACE XXXX; 是无法将数据文件一同都删除的 想要删除表空间和数据文件需要如下操作: SQL> drop tablespace XX ...

  6. 【一天一个知识点系列】- Redis Cluser之数据分布

    数据分布 简述 分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集 分区及限制 分区规则 常见的分区规则 顺序分区 哈希分区 ...

  7. [从源码学设计]蚂蚁金服SOFARegistry之延迟操作

    [从源码学设计]蚂蚁金服SOFARegistry之延迟操作 0x00 摘要 SOFARegistry 是蚂蚁金服开源的一个生产级.高时效.高可用的服务注册中心. 本系列文章重点在于分析设计和架构,即利 ...

  8. 接收的参数为日期类型、controller控制层进行数据保存、进行重定向跳转

    目录 1.接收的参数为日期类型 2.controller控制层进行数据保存 3.controller层如何进行重定向跳转(因为默认是请求转发) 4.静态资源的映射 1.接收的参数为日期类型 WEB-I ...

  9. 在EXCEL中如何同时冻结行与列?

    鼠标所在的单元格的位置 ,决定了你冻结的行和列.如: 冻结第一行与第一列, 只需要将鼠标置于单元格在第二列,第二行. 点击冻结

  10. 全栈性能测试修炼宝典-JMeter实战笔记(二)

    性能测试初体验 性能测试实质:利用工具去模拟大量用户操作来验证系统能够承受的负载情况,找出潜在的性能问题,分析并解决:找出系统性能变化趋势,为后续的扩展提供参考 测试分类 测试内容中,负载测试.压力测 ...