Description

你有一个无向连通图,边的总数为偶数。

设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除)。对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的路径将u和v连接。每条路径允许经过重复的点,但不允许经过重复的边。这k/2条路径之间也不能有重复的边。

Input

第一行有两个整数n,m(2<=n,m<=250000),分别表示点数、边数,m为偶数。

接下来m行,每行两个整数a,b(1<=a,b<=n,a≠b),表示a,b间连有一条边。不存在重边。保证奇点的数目不为零。

Output

如果你认为无解就输出NIE。

设图中有k个奇点,则输出由k/2部分组成,每个部分包含两行:第一行为u,v,l,表示连接的两个点,及路径长度。第二行为空格隔开的l个整数,表示u到v的路径。边按照输入顺序从1到m编号。

若有多组答案,任意输出其中一个。

Sample Input

6 8

1 2

2 3

3 4

4 5

5 6

6 1

1 4

2 5

Sample Output

样例输出:

1 5 2

6 5

2 4 2

8 4

另一种合法输出:

1 5 6

1 2 3 7 6 5

2 4 2

8 4

Solution

这题是个好题兼难题

考虑假如没有路径长度为偶数的限制,那么就是把奇度数点两两配对连边,使得所有的点的度数均为偶数,然后跑欧拉回路;或者建一个新点,从它向所有奇点连边,起到同样的效果

然而现在有了长度为偶数的限制,就不能简单这样连边了

把每个点 \(u\) 拆点 \(u_{left}\) 与 \(u_{right}\) ,建成二分图,建一个新点向所有奇点的 \(u_{left}\) 连边

考虑这个二分图的作用,我们如果能把原图中的边转换成二分图中的边,然后有一条 \(u_{left}\) 到 \(v_{left}\) 的路径,那么这条路径一定是偶数长度的(二分图的特性)

所以我们想要达到这样一种状态,这个二分图里有原图中的边,然后特殊点(即新建的那个点)与所有原图中奇度数点有边相连,同时二分图中每个点的度数都是偶数。如果达到了这样一个状态,那么只要从特殊点开始跑一条欧拉回路,答案就出来了

怎样达到这样的状态是个棘手的问题。首先看二分图有什么性质。如果 \(u_{left}\) 在二分图里的度数为偶数,那么 \(u_{right}\) 的度数也一定为偶数。因为在原图中所有点都是偶数度数(加了特殊点的边之后),而 \(d[u_{left}]+d[u_{right}]=u\) 在原图中的度数,如果保证了 \(u_{left}\) 的度数为偶数,那么 \(u_{right}\) 的度数必定也是偶数

所以我们只要维持二分图左边的所有点的度数为偶数就好了

考虑拉出原图的一棵生成树,剩下的边在二分图中随意连,因为无论连出来的度数怎样,生成树都可以进行调整

剩下的边任意连完后,从叶子到根遍历生成树。当前到了 \(x\) 点,如果 \(x_{left}\) 的度数现在是奇数,那么 \(x\) 到 \(fa[x]\) 的这条边在二分图中就连 \(x_{left}\) 到 \(fa[x]_{right}\) ,这样做就可以把 \(x_{left}\) 的度数从奇数调成偶数;反之同理

由于是从叶子到根遍历的,我们把一个点的度数调整好为奇数后就不会再被改变了

那么二分图要达到的状态便完成了

跑完欧拉回路考虑怎么找答案

我们建了一个特殊点,这些特殊点向所有原图中的奇度数点的 \(left\) 点都连了边,所以跑欧拉回路,要求所有边都遍历到,那么每次从特殊点出去一次,必定也会回来一次,而出去所到的点与回来出发的点都是 \(left\) 点,正好满足路径长度为偶数的性质,于是,只要在欧拉路径中找不包含特殊点的极长段,这一段两端的点就是题目要求的一条路径的两个点,这一段中间的点就是要经过的点,稍加处理就好了

#include<bits/stdc++.h>
#define ui unsigned int
#define ll long long
#define db double
#define ld long double
#define ull unsigned long long
const int MAXN=500000+10;
int n,m,e=1,beg[MAXN],nex[MAXN<<1],to[MAXN<<1],was[MAXN<<1],d[MAXN],nd[MAXN],tp,ansp[MAXN],sum,path[MAXN<<1],use[MAXN<<1],cnt,fa[MAXN],pre;
struct node{
int u,v,id;
};
node side[MAXN];
std::vector<int> G[MAXN];
std::map<int,int> M[MAXN];
template<typename T> inline void read(T &x)
{
T data=0,w=1;
char ch=0;
while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
if(ch=='-')w=-1,ch=getchar();
while(ch>='0'&&ch<='9')data=((T)data<<3)+((T)data<<1)+(ch^'0'),ch=getchar();
x=data*w;
}
template<typename T> inline void write(T x,char ch='\0')
{
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+'0');
if(ch!='\0')putchar(ch);
}
template<typename T> inline void chkmin(T &x,T y){x=(y<x?y:x);}
template<typename T> inline void chkmax(T &x,T y){x=(y>x?y:x);}
template<typename T> inline T min(T x,T y){return x<y?x:y;}
template<typename T> inline T max(T x,T y){return x>y?x:y;}
inline void insert(int x,int y,int z)
{
to[++e]=y;
nex[e]=beg[x];
beg[x]=e;
was[e]=z;
}
inline int found(int x)
{
if(fa[x]!=x)fa[x]=found(fa[x]);
return fa[x];
}
inline void dfs(int x,int f)
{
for(register int i=0,lt=G[x].size();i<lt;++i)
if(G[x][i]==f)continue;
else dfs(G[x][i],x);
if(x==1)return ;
if(nd[x]&1)insert(x,f+n,M[x][f]),insert(f+n,x,M[x][f]),nd[x]++;
else insert(x+n,f,M[x][f]),insert(f,x+n,M[x][f]),nd[f]++;
}
inline void eulerdfs(int x)
{
for(register int &i=beg[x];i;i=nex[i])
if(!use[i]&&!use[i^1])
{
int tmp=i;
use[i]=use[i^1]=1;
eulerdfs(to[i]);
path[++cnt]=tmp;
}
}
int main()
{
read(n);read(m);
for(register int i=1;i<=m;++i)
{
int u,v;read(u);read(v);
d[u]++;d[v]++;
side[i]=(node){u,v,i};
}
for(register int i=1;i<=n;++i)
{
fa[i]=i;
if(d[i]&1)insert(0,i,m+i),insert(i,0,m+i),nd[i]++;
}
for(register int i=1;i<=m;++i)
{
int u=found(side[i].u),v=found(side[i].v);
if(u==v)insert(side[i].u,side[i].v+n,side[i].id),insert(side[i].v+n,side[i].u,side[i].id),nd[side[i].u]++;
else G[side[i].u].push_back(side[i].v),G[side[i].v].push_back(side[i].u),M[side[i].u][side[i].v]=M[side[i].v][side[i].u]=side[i].id,fa[u]=v;
}
dfs(1,0);
eulerdfs(0);
while(cnt)
{
while(cnt&&!to[path[cnt]])cnt--;
if(cnt<=0)break;
sum=0;pre=to[path[cnt]];
int ps=cnt;
while(ps&&to[path[ps]])sum++,ps--;
printf("%d %d %d\n",pre,to[path[ps+1]],sum-1);
for(register int i=cnt-1;i>ps;--i)printf("%d ",was[path[i]]);puts("");
cnt=ps;
}
return 0;
}

【刷题】BZOJ 3724 PA2014Final Krolestwo的更多相关文章

  1. @bzoj - 3724@ PA2014Final Krolestwo

    目录 @description@ @solution@ @accepted code@ @details@ @description@ 你有一个无向连通图,边的总数为偶数. 设图中有k个奇点(度数为奇 ...

  2. 【刷题】BZOJ 2407 探险

    Description 探险家小T好高兴!X国要举办一次溶洞探险比赛,获奖者将得到丰厚奖品哦!小T虽然对奖品不感兴趣,但是这个大振名声的机会当然不能错过! 比赛即将开始,工作人员说明了这次比赛的规则: ...

  3. 【刷题】BZOJ 4543 [POI2014]Hotel加强版

    Description 同OJ3522 数据范围:n<=100000 Solution dp的设计见[刷题]BZOJ 3522 [Poi2014]Hotel 然后发现dp的第二维与深度有关,于是 ...

  4. 【刷题】BZOJ 4316 小C的独立集

    Description 图论小王子小C经常虐菜,特别是在图论方面,经常把小D虐得很惨很惨. 这不,小C让小D去求一个无向图的最大独立集,通俗地讲就是:在无向图中选出若干个点,这些点互相没有边连接,并使 ...

  5. 【刷题】BZOJ 4176 Lucas的数论

    Description 去年的Lucas非常喜欢数论题,但是一年以后的Lucas却不那么喜欢了. 在整理以前的试题时,发现了这样一道题目"求Sigma(f(i)),其中1<=i< ...

  6. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

  7. 【刷题】BZOJ 2260 商店购物

    Description Grant是一个个体户老板,他经营的小店因为其丰富的优惠方案深受附近居民的青睐,生意红火.小店的优惠方案十分简单有趣.Grant规定:在一次消费过程中,如果您在本店购买了精制油 ...

  8. 【刷题】BZOJ 4566 [Haoi2016]找相同字符

    Description 给定两个字符串,求出在两个字符串中各取出一个子串使得这两个子串相同的方案数.两个方案不同当且仅当这两个子串中有一个位置不同. Input 两行,两个字符串s1,s2,长度分别为 ...

  9. 【刷题】BZOJ 3365 [Usaco2004 Feb]Distance Statistics 路程统计

    Description 在得知了自己农场的完整地图后(地图形式如前三题所述),约翰又有了新的问题.他提供 一个整数K(1≤K≤109),希望你输出有多少对农场之间的距离是不超过K的. Input 第1 ...

随机推荐

  1. 【小程序】访问 https配置的数据接口

    小程序对于网络请求的URL的特殊要求:1)不能出现端口号;    2)不能用localhost;       3)  必须用https (一)搭建本地https服务器(windows) 搭建出来的服务 ...

  2. THUSC 2017 D1T2 杜老师

    这是个非常有趣的数学题啦... 其实大概推一推式子就能得到一个信息,就是答案一定是$2$的整数次幂,并且其实答案就是$2^{R-L+1-sum}$,其中$sum$表示有多少个数不能用$L-i-1$的数 ...

  3. Android开发——监听Android手机的网络状态

    0. 前言 在Android开发中监听手机的网络状态是一个常见的功能,比如在没网的状态下进行提醒并引导用户打开网络设置,或者在非wifi状态下开启无图模式等等.因此本篇将网上的资料进行了整理总结,方便 ...

  4. POJ3267

    从今天开始POJ里的一部分类型的题目就一般不放在一起写了 一个是太丑,格式麻烦,第二个是以后的题目难度都有所增大,因此一道题可能就要写蛮长 尤其是DP这一块,以前一直没好好学习,现在从基础的先开始吧 ...

  5. Solr 后台查询实例 (工作备查)

    有时间再进行整理package xxx.service.impl; import java.util.HashMap; import java.util.Map; import java.util.M ...

  6. petapoco 对存储过程的扩展 干货

    好久没发表文章了.心血来潮,简单的介绍下这次工作中的问题. 项目中运用了Petapoco,可是petapoco对存储过程的支持不够好.或者说对于某些特殊场景,petapoco的sql支持度有限. 比如 ...

  7. redis启动停止+密码认证

    redis启动停止命令 ./bin/redis-server redis.conf ./bin/redis-cli -h 127.0.0.1 -p 6379 shutdown flushall ——& ...

  8. Scrum立会报告+燃尽图(十二月十一日总第四十二次):贡献分配和收集用户报告

    此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2484 项目地址:https://git.coding.net/zhang ...

  9. linux内核分析--计算机是如何工作的

    实验部分 使用gcc -S -o main.s main.c -m32命令将源代码编译成汇编代码. 源代码如下: int g(int x) { return x + 9; } int f(int x) ...

  10. Linux内核分析(第二周)

    操作系统是如何工作的? 一.总结:三大法宝 1.存储程序计算机 + 函数调用堆栈 + 中断机制 2.堆栈:C语言程序运行时候必须的一个记录调用路径和参数的空间(函数调用框架/提供局部变量/传递参数/保 ...