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. oracle版本兼容问题

    问题一描述:本机环境升级为vs2012升级TLS程序为framework4.0,本机ODAC为ODTwithODAC112030.本机为oracle10g本机程序生成成功,运行成功. 发布到服务器后, ...

  2. SJA1000 CAN驱动程序演示实验

    SJA1000 CAN驱动程序演示实验 2016-04-12 20:41:22来源: eefocus 关键字:SJA1000  CAN  驱动程序  演示实验   收藏 评论(0) 分享到 微博 QQ ...

  3. iOS开发之使用UIView-Positioning简化页面布局

    使用过代码布局的人可能会有这样的感觉,给控件设置frame的时候比较繁琐.最 近在Github上看到有一个UIView的一个分类UIView-Positioning,这个分类提供了一些属性,比如lef ...

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

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

  5. 【H5】滚动事件(jq)

    $(function(){ console.log($('html,body').scrollTop());  //记录滚动高度(滚动前) }) $('html,body').scroll(funct ...

  6. jenkis +sonarqube 对后端代码静态扫描,钉钉群通知执行结果(记录)

    代码提交,触发后端sonar测试,测试完成,jenkins触发依赖任务,执行python脚本,达到预期,调用上线任务模块,进行上线,达不到预期,钉钉群通知. 牵涉到配置: 1.配置sonar测试任务 ...

  7. 解决SSH登录用户执行的命令部分环境变量参数不生效的问题

    问题概况 linux机器在/etc/profile配置完成环境变量后,SSH到目标机器执行命令,但是获取不到已配置的环境变量值. 例如场景: 在/etc/profile配置了http代理 export ...

  8. tcp ,http .udp

    三次握手,四次挥手要知道,记住. 计算机协议常见面试题,学会了,记住.会运用.

  9. C#易忘点

    下面是自己总结的一些C#语言方面用的少容易忘的地方,总结一下,在用的时候看一下.(仅针对本人) 参数数组 定义一个函数,用来取得数字的和,但是数字的个数不确定. 解决方案: 1,定义一个函数,参数传递 ...

  10. ElasticSearch读写原理

    es 写入数据的工作原理是什么啊?es 查询数据的工作原理是什么啊?底层的 lucene 介绍一下呗?倒排索引了解吗? es 写数据过程 客户端选择一个 node 发送请求过去,这个 node 就是  ...