Wizard's Tour
2 seconds
256 megabytes
standard input
standard output
All Berland residents are waiting for an unprecedented tour of wizard in his Blue Helicopter over the cities of Berland!
It is well-known that there are n cities in Berland, some pairs of which are connected by bidirectional roads. Each pair of cities is connected by no more than one road. It is not guaranteed that the road network is connected, i.e. it is possible that you can't reach some city from some other.
The tour will contain several episodes. In each of the episodes:
- the wizard will disembark at some city x from the Helicopter;
- he will give a performance and show a movie for free at the city x;
- he will drive to some neighboring city y using a road;
- he will give a performance and show a movie for free at the city y;
- he will drive to some neighboring to y city z;
- he will give a performance and show a movie for free at the city z;
- he will embark the Helicopter and fly away from the city z.
It is known that the wizard doesn't like to use roads, so he agrees to use each road at most once (regardless of direction). In other words, for road between a and b he only can drive once from a to b, or drive once from b to a, or do not use this road at all.
The wizards wants to plan as many episodes as possible without violation the above rules. Help the wizard!
Please note that the wizard can visit the same city multiple times, the restriction is on roads only.
The first line contains two integers n, m (1 ≤ n ≤ 2·105, 0 ≤ m ≤ 2·105) — the number of cities and the number of roads in Berland, respectively.
The roads description follow, one in each line. Each description is a pair of two integers ai, bi (1 ≤ ai, bi ≤ n, ai ≠ bi), where ai and bi are the ids of the cities connected by the i-th road. It is guaranteed that there are no two roads connecting the same pair of cities. Every road is bidirectional. The cities are numbered from 1 to n.
It is possible that the road network in Berland is not connected.
In the first line print w — the maximum possible number of episodes. The next w lines should contain the episodes in format x, y, z — the three integers denoting the ids of the cities in the order of the wizard's visits.
4 5
1 2
3 2
2 4
3 4
4 1
2
1 4 2
4 3 2
5 8
5 3
1 2
4 5
5 1
2 5
4 3
1 4
3 2
4
1 4 5
2 3 4
1 5 3
5 2 1
分析:给一个图,求最多能组成多少个V图形,其中每条边只能用一次;
可以证明,对于每个联通块,最多可以组成edge/2个V图形;
考虑递归处理;
对于当前节点,标记所有没用的边,并把节点放入当前集合;
递归处理集合中的节点,如果没有访问过,则递归该节点;
如果递归返回一个节点,说明有未配对边,与当前边配对;
否则,当前边未配对,在全部结束后两两配对即可;
若配对后剩下一条边,返回到父亲即可;
代码:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <climits>
#include <cstring>
#include <string>
#include <set>
#include <bitset>
#include <map>
#include <queue>
#include <stack>
#include <vector>
#include <cassert>
#include <ctime>
#define rep(i,m,n) for(i=m;i<=(int)n;i++)
#define inf 0x3f3f3f3f
#define mod 1000000007
#define vi vector<int>
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define ll long long
#define pi acos(-1.0)
#define pii pair<int,int>
#define sys system("pause")
#define ls (rt<<1)
#define rs (rt<<1|1)
#define all(x) x.begin(),x.end()
const int maxn=2e5+;
const int N=2e5+;
using namespace std;
ll gcd(ll p,ll q){return q==?p:gcd(q,p%q);}
ll qmul(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=(f+p)%mo;p=(p+p)%mo;q>>=;}return f;}
ll qpow(ll p,ll q,ll mo){ll f=;while(q){if(q&)f=f*p%mo;p=p*p%mo;q>>=;}return f;}
int n,m,k,t;
map<ll,int>p,w;
vi e[maxn];
bool vis[maxn];
struct node
{
int x,y,z;
};
vector<node>ret;
bool ok(int x,int y,int z)
{
int ex=x,ey=y;
if(ex>ey)swap(ex,ey);
w[1LL*ex*N+ey]=;
ex=y,ey=z;
if(ex>ey)swap(ex,ey);
w[1LL*ex*N+ey]=;
}
int dfs(int x)
{
int i;
vis[x]=true;
vi bl;
rep(i,,e[x].size()-)
{
int y=e[x][i];
int z=x;
if(y>z)swap(y,z);
if(!p.count(1LL*y*N+z))
{
bl.pb(e[x][i]),
p[1LL*y*N+z]=;
}
}
rep(i,,bl.size()-)
{
int y=bl[i];
if(vis[y])continue;
int z=dfs(y);
if(z)ret.pb(node{x,y,z}),ok(x,y,z);
}
int y=,z=;
rep(i,,bl.size()-)
{
z=bl[i];
if(!w.count(1LL*min(z,x)*N+max(z,x)))
{
if(y)
{
ret.pb(node{y,x,z});
ok(y,x,z);
y=z=;
}
else y=z,z=;
}
}
return y;
}
int main(){
int i,j;
scanf("%d%d",&n,&m);
rep(i,,m)
{
int x,y;
scanf("%d%d",&x,&y);
e[x].pb(y),e[y].pb(x);
}
rep(i,,n)if(!vis[i])dfs(i);
printf("%d\n",ret.size());
rep(i,,ret.size()-)
{
printf("%d %d %d\n",ret[i].x,ret[i].y,ret[i].z);
}
return ;
}
Wizard's Tour的更多相关文章
- 【Codeforces858F】Wizard's Tour [构造]
Wizard's Tour Time Limit: 50 Sec Memory Limit: 512 MB Description Input Output Sample Input 4 5 1 2 ...
- CodeForces 860D Wizard's Tour
题意 给出一张无向图,要求找出尽量多的长度为2的不同路径(边不可以重复使用,点可以重复使用) 分析 yzy:这是原题 http://www.lydsy.com/JudgeOnline/problem. ...
- CF858F Wizard's Tour 解题报告
题目描述 给定一张 \(n\) 个点 \(m\) 条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通. 你想在这张图上进行若干次旅游,每次旅游可以任选一个点 \(x\) 作为起点,再走到一个 ...
- CF858F Wizard's Tour
也许更好的阅读体验 \(\mathcal{Description}\) 给定一张 \(n\) 个点 \(m\) 条边的无向图,每条边连接两个顶点,保证无重边自环,不保证连通. 你想在这张图上进行若干次 ...
- Wizard's Tour CodeForces - 860D (图,构造)
大意: 给定$n$节点$m$条边无向图, 不保证连通, 求选出最多邻接边, 每条边最多选一次. 上界为$\lfloor\frac{m}{2}\rfloor$, $dfs$贪心划分显然可以达到上界. # ...
- 「CF858F」 Wizard's Tour
传送门 Luogu 解题思路 首先对于树的情况,我们很显然有一种贪心策略: 对于每一个节点先匹配子树,然后在还可以匹配的儿子间尽可能匹配,要是多出来一个就往上匹配. 推广到图的情况... 我们在图的生 ...
- Codeforces Round #434 (Div. 2)
Codeforces Round #434 (Div. 2) 刚好时间对得上,就去打了一场cf,发现自己的代码正确度有待提高. A. k-rounding 题目描述:给定两个整数\(n, k\),求一 ...
- salesforce 零基础学习(六十)Wizard样式创建数据
项目中表之间关联关系特别多,比如三个表中A,B,C C作为主表,A,B作为从表,有时候C表需要创建数据时,同时需要创建A,B两个表的数据,这种情况下,使用Wizard样式会更加友好. 以Goods_ ...
- Wizard Framework:一个自己开发的基于Windows Forms的向导开发框架
最近因项目需要,我自己设计开发了一个基于Windows Forms的向导开发框架,目前我已经将其开源,并发布了一个NuGet安装包.比较囧的一件事是,当我发布了NuGet安装包以后,发现原来已经有一个 ...
随机推荐
- Scikit-learn库中的数据预处理(一)
数据标准化:当单个特征的样本取值相差甚大或明显不遵从高斯正态分布时,标准化表现的效果较差.实际操作中,经常忽略特征数据的分布形状,移除每个特征均值,划分离散特征的标准差,从而等级化,进而实现数据中心化 ...
- 在LNMP或Nginx上配置NameCheap免费SSL证书
- codevs3162抄书问题(划分型dp)
3162 抄书问题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 现在要把M本有顺序的书分给K个人复制(抄写),每 ...
- [App Store Connect帮助]一、 App Store Connect 使用入门(4)iOS 版 App Store Connect
通过 iOS 版 App Store Connect,您可以在移动设备上查看销售数据.App 元数据和顾客评论.您还可以检查 App 状态.发布您 App 的新版本并回应“Resolution Cen ...
- JavaScript中对象转换为原始值的规则
JavaScript中对象转换为原始值遵循哪些原则? P52 对象到布尔值对象到布尔值的转换非常简单:所有的对象(包括数字和函数)都转换为true.对于包装对象亦是如此:new Boolean(fal ...
- C#最实用的快捷键
Ctrl+J(Alt+→):智能提示. Ctrl+X:删除整行. Shift+Alt+Enter:全屏切换 F12:跳转到定义. Ctrl+-.Ctrl+Shift+-:上一步.下一步(仅限于使用过上 ...
- android黑科技系列——自动注入代码工具icodetools
一.前言 在前面已经介绍完了 自动给apk中注入日志代码工具icodetools原理了,在那里我们曾经说过其实离真正的可使用价值有点距离,本篇就对这个工具进行一些优化,让其真正意义上开始能工作量产.当 ...
- [Android]异常1-duplicate files during packaging of
异常原因: 可能一>项目存在重复资源文件 可能二>Android Studio与源代码Android Studio不一致 解决方法有: 解决一>查找重复资源,删除或者修改文件 解决二 ...
- ajax不执行success的问题
有时候经常会遇到ajax请求后台,然后后台返回数据后,不触发ajax的success函数的问题,归根到底,这与ajax的参数设置dataType和后台的返回值的类型有关,现总结如下: 一.后台返回值的 ...
- Escaping Closures 两点:本质是生命周期标示符
1.block需要(拷贝)保存: 2.block引用的环境变量需要处理. 相当于oc中的copy block. Escaping Closures A closure is said to escap ...