题目描述

给定一张 \(n\) 个点 \(m\) 条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通。

你想在这张图上进行若干次旅游,每次旅游可以任选一个点 \(x\) 作为起点,再走到一个与 \(x\) 直接有边相连的点 \(y\),再走到一个与 \(y\) 直接有边相连的点 \(z\) 并结束本次旅游。

作为一个旅游爱好者,你不希望经过任意一条边超过一次,注意一条边不能即正向走一次又反向走一次,注意点可以经过多次,在满足此条件下,你希望进行尽可能多次的旅游,请计算出最多能进行的旅游次数并输出任意一种方案。

输入输出格式

输入格式

第 \(1\) 行两个正整数 \(n\) 与 \(m\),表示全图的点数与边数

下接 \(m\) 行,每行两个数字 \(u\) 与 \(v\) 表示一条边

输出格式

第 \(1\) 行一个整数 \(cnt\) 表示答案

下接 \(cnt\) 行,每行三个数字 \(x, y\) 与 \(z\),表示一次旅游的路线

如有多种旅行方案,任意输出一种即可

说明

对于前 \(20\%\) 的数据, \(n \le10, m \le 20\).

对于另 \(20\%\) 的数据, \(m = n - 1\),并且图连通

对于另 \(10\%\) 的数据,每个点的度数不超过 \(2\)

对于 \(100\%\) 的数据, \(n \le 100000, m \le 200000\)


可能还是没怎么做过构造题目吧,我打的树的特殊数据分其实改一改就是正解了。

通过手玩我们发现对一个有\(m\)条边的连通块来说,方案数量一定可以构造到\(\lfloor\frac{m}{2}\rfloor\)个。

构造方法如下

对某个连通块随便选择一个点构造一颗搜索树,在回溯的时候配对可以连接的边,如果不能两两配对,那么用上自己头上的边。

考虑为什么这样是对的,思路很简单。我们发现除了选定根的某个儿子边,所有的边都可以用上,不会产生浪费。


Code:

#include <cstdio>
#include <vector>
#define rep(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,a,b) for(int i=a;i<b;i++)
#define ed() for(int i=head[now];i;i=Next[i])
#define pb(a) push_back(a)
const int N=2e5+10;
int head[N],to[N<<1],Next[N<<1],cnt=1;
void add(int u,int v)
{
to[++cnt]=v,Next[cnt]=head[u],head[u]=cnt;
}
int used[N<<1],ans[N<<2],n,m,tot,vis[N];
void dfs(int now,int fa,int edg)
{
vis[now]=1;
std::vector <int> ch;
ed()
{
int v=to[i];
if(v!=fa&&!vis[v]) dfs(v,now,i);
}
ed()
{
int v=to[i];
if(v!=fa&&!used[i])
{
ch.pb(i);
used[i^1]=1;
}
}
Rep(i,0,ch.size())
{
if(i&1) ans[++tot]=now;
ans[++tot]=to[ch[i]];
}
if(ch.size()&1)
{
if(fa) ans[++tot]=now,ans[++tot]=fa,used[edg]=1;
else tot--;
}
}
int main()
{
scanf("%d%d",&n,&m);
int u,v;
rep(i,1,m) scanf("%d%d",&u,&v),add(u,v),add(v,u);
rep(i,1,n) if(!vis[i]) dfs(i,0,0);
printf("%d\n",tot/3);
rep(i,1,tot)
{
printf("%d ",ans[i]);
if(i%3==0) printf("\n");
}
return 0;
}

2018.10.25

最新文章

  1. [NHibernate]代码生成器的使用
  2. 多线程下NSOperation、NSBlockOperation、NSInvocationOperation、NSOperationQueue的使用
  3. Python之路-python(mysql介绍和安装、pymysql、ORM sqlachemy)
  4. PLSQL_基础系列02_分组函数GROUP BY / ROLLUP / CUBE(案例)
  5. 检测js代码是否已加载的判断代码
  6. Codeforces 158E Phone Talks
  7. [译]Stairway to Integration Services Level 12 - 高级日志配置
  8. 困扰你的private static final long serialVersionUID
  9. OSI模型和TCP/IP协议族(二)
  10. Cookiecutter: 更好的项目模板工具:(2)安装及基础使用
  11. Delphi中Chrome Chromium、Cef3学习笔记(二)
  12. Python文件和异常
  13. 小型IT部门建设之我见
  14. POJ 2243 Knight Moves(BFS)
  15. Intellij Idea 使用时总是打开上次的项目
  16. Maven让资源文件处理插件能够解析资源文件中的Maven属性
  17. Rhino
  18. 梯度提升树GBDT算法
  19. [EffectiveC++]item16:Use the same form in corresponding uses of new and delete
  20. Docker入门简明教程

热门文章

  1. pyqt5--学习资料
  2. php中 include 、include_once、require、require_once4个语言结构的含义和区别
  3. hive 学习系列三(表格的创建create-table)
  4. Python基本图形绘制
  5. POJ1659 可图性判定
  6. Druid时序数据库常见问题及处理方式
  7. c# string.format和tostring()
  8. 1,理解java中的IO
  9. PHP管理供下载的APK文件
  10. 第三篇 Fiddler数据包分析