如果没有长度为偶数的限制,新建一个点向所有奇点连边,跑欧拉回路即可,显然此时一定存在欧拉回路,因为所有点度数都为偶数。

  考虑长度为偶数的限制,将每个点拆成两个点放进一个二分图里,那么每条原图中的边在二分图中会对应两条边,一条长度为偶数的路径在二分图中显然是由某部分出发再走回这部分。我们需要让每条原图中的边恰在二分图中出现一次,且保证所有点度数为偶数,这样仍然跑个欧拉回路就完了。

  对原图任意取一棵生成树。让非树边任意连,然后通过树边调整度数以达到目的。注意到新建点并连边后,原图中所有点度数都为偶数,而原图中的点在二分图中的对应两点度数之和,就是该点在原图中的度数,也即偶数。也就是说任意点的对应两点度数奇偶性相同,调整一条与其相连的边会同时改变这两点的度数奇偶性。于是考虑怎么调整树边,自底向上,如果某点的儿子当前不满足条件,就改变这条边的连接方式,显然这样儿子的度数就合法了。不断调整上去,最后只剩下根,不过事实上根此时已经合法,因为边的总数是偶数,二分图某边的点度数之和也是偶数,不可能只有根的度数是奇数。

  悲惨地发现darkbzoj没有spj,那就精神AC吧(感觉浑身是bug)。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<map>
using namespace std;
#define ll long long
#define N 500010
char getc(){char c=getchar();while ((c<'A'||c>'Z')&&(c<'a'||c>'z')&&(c<'0'||c>'9')) c=getchar();return c;}
int gcd(int n,int m){return m==0?n:gcd(m,n%m);}
int read()
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
int n,m,p[N],degree[N],dir[N],t=-1;
map<int,int> id[N];
bool flag[N],vis[N];
struct data{int to,nxt;
}edge[N<<1];
void addedge(int x,int y){t++;degree[y]++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;}
namespace bigraph
{
int p[N],cur[N],degree[N],stk[N<<1],m=0,top=0,cnt=0,t=-1;
bool flag[N];
struct data{int to,nxt;}edge[N<<1];
void addedge(int x,int y)
{
t++;degree[y]++;edge[t].to=y,edge[t].nxt=p[x],p[x]=t;
t++;degree[x]++;edge[t].to=x,edge[t].nxt=p[y],p[y]=t;
m++;
}
void find(int k)
{
for (int i=cur[k];~i;i=edge[i].nxt)
if (!flag[i>>1])
{
flag[i>>1]=1;cnt++;
cur[k]=edge[i].nxt;
find(edge[i].to);
if (cnt==m) break;
}
stk[++top]=k;
}
void print()
{
reverse(stk+1,stk+top+1);//for (int i=1;i<=top;i++) cout<<stk[i]<<' ';cout<<endl;
for (int i=1;i<=top;i++)
{
if (i==top) break;
int x=++i,y;
for (int j=i+1;j<=top;j++)
if (stk[j]==0) {y=j-1;break;}
printf("%d %d %d\n",stk[x],stk[y],y-x);
for (int j=x;j<y;j++)
printf("%d ",id[(stk[j]-1)%n+1][(stk[j+1]-1)%n+1]);printf("\n");
i=y;
}
}
}
void dfs(int k)
{
vis[k]=1;
for (int i=p[k];~i;i=edge[i].nxt)
if (!vis[edge[i].to])
{
dfs(edge[i].to);
flag[i>>1]=1;
}
}
void getdir(int k,int from)
{
for (int i=p[k];~i;i=edge[i].nxt)
if (flag[i>>1]&&edge[i].to!=from)
{
getdir(edge[i].to,k);
if (bigraph::degree[edge[i].to]&1) dir[i>>1]=i&1^1;
else dir[i>>1]=i&1,bigraph::degree[k]^=1;
}
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("bzoj3724.in","r",stdin);
freopen("bzoj3724.out","w",stdout);
const char LL[]="%I64d\n";
#else
const char LL[]="%lld\n";
#endif
n=read(),m=read();memset(p,255,sizeof(p));
for (int i=1;i<=m;i++)
{
int x=read(),y=read();
addedge(x,y),addedge(y,x);
id[x][y]=id[y][x]=i;
}
dfs(1);
for (int i=0;i<t;i+=2) if (!flag[i>>1]) bigraph::degree[edge[i^1].to]^=1;
for (int i=1;i<=n;i++) if (degree[i]&1) bigraph::degree[i]^=1;
getdir(1,1);
memset(bigraph::p,255,sizeof(bigraph::p));
for (int i=0;i<t;i+=2) bigraph::addedge(edge[i^1].to+dir[i>>1]*n,edge[i].to+(dir[i>>1]^1)*n);
for (int i=1;i<=n;i++) if (degree[i]&1) bigraph::addedge(0,i);
memcpy(bigraph::cur,bigraph::p,sizeof(bigraph::cur));
bigraph::find(0);
bigraph::print();
return 0;
}

  

BZOJ3724 PA2014Final Krolestwo(欧拉回路+构造)的更多相关文章

  1. BZOJ3724PA2014Final Krolestwo——欧拉回路+构造

    题目描述 你有一个无向连通图,边的总数为偶数.设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的 ...

  2. hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现

    http://acm.hdu.edu.cn/showproblem.php? pid=4850 题意:构造长度为n的字符序列.使得>=4的子串仅仅出现一次 事实上最长仅仅能构造出来26^4+4- ...

  3. 【刷题】BZOJ 3724 PA2014Final Krolestwo

    Description 你有一个无向连通图,边的总数为偶数. 设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每 ...

  4. CF36E Two Paths (欧拉回路+构造)

    题面传送门 题目大意:给你一张可能有重边的不保证联通的无向图,现在要在这个图上找出两条路径,恰好能覆盖所有边一次,根据边的编号输出方案,无解输出-1 一道很不错的欧拉路径变形题 首先要知道关于欧拉路径 ...

  5. @bzoj - 3724@ PA2014Final Krolestwo

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

  6. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  7. NOI前训练日记

    向别人学习一波,记点流水帐.17.5.29开坑. 5.29 早晨看了道据说是树状数组优化DP的题(hdu5542),然后脑补了一个复杂度500^3的meet in the middle.然后死T... ...

  8. IOI 2020 集训队作业胡扯

    首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...

  9. 2015多校.MZL's endless loop(欧拉回路的机智应用 || 构造)

    MZL's endless loop Time Limit: 3000/1500 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Oth ...

随机推荐

  1. Android ScrollView和ListView联用,且ListView可以下拉刷新和上拉加载

    ScrollView嵌套listView且ListView可以实现上拉加载. 由于代码太长,在此只提供实现思路: 先不说上拉加载的事,咱们先回想一下,ScrollView和LsitView联用,时的解 ...

  2. 谈高清显示接口HDMI、RGB、LVDS、MIPI、eDP、mini-LVDS、V-By-One

    近年来随着电子产业的高速发展,智能显示设备也取得了辉煌的成就,高清显示得到了消费者的青睐.目前高清显示协议接口有RGB.LVDS.MIPI.eDP.HDMI.miniLVDS.V-by-One等,由于 ...

  3. postgrepsql 创建函数

    -- 这里的CREATE OR REPLACE FUNCTION 为固定写法:   "public"."function_info_a1" 这个为函数名   C ...

  4. Angularjs实现select的下拉列表

    练习使用angularjs实现一个select下拉列表: <div ng-app="selectApp" ng-controller="selectControll ...

  5. [转]curl的错误代码

    转贴者按: 今天在使用curl的时候碰到了一个错误,如下所示: External Program Failed: D:\Tools\curl\curl.exe (return code was 18) ...

  6. Luogu P2286 [HNOI2004]宠物收养场

    一道比较简单的直接Treap运用题目,思维难度和代码难度都不是很高. 题意有点长,我们仔细剖析一下题意发现以下几个关键: 任何时候收养站里只可能有人和宠物中的其中一种,或者都没有 如果只有宠物并有人来 ...

  7. 暴雪《争霸艾泽拉斯》*采用自适应 SSAO

    在实时渲染过程中,屏幕空间环境光遮蔽 (SSAO) 常用于打造小范围环境光效果和接触阴影效果.它用于许多现代游戏,通常占用 5% 到 10% 的帧时间.在<争霸艾泽拉斯>* 游戏开发过程中 ...

  8. Redis数据"丢失"讨论及规避和解决的几点总结

    Redis大部分应用场景是纯缓存服务,请求后端有Primary Storage的组件,如MySQL,HBase;请求Redis的键未命中,会从primary Storage中获取数据返回,同时更新Re ...

  9. Linux内核分析第三章读书笔记

    第三章 进程管理 3.1 进程 进程就是处于执行期的程序 进程就是正在执行的程序代码的实时结果 线程:在进程中活动的对象.每个线程都拥有一个独立的程序计数器.进程栈和一组进程寄存器. 内核调度的对象是 ...

  10. linux及安全第八周总结

    进程的调度时机与进程的切换 操作系统原理中介绍了大量进程调度算法,这些算法从实现的角度看仅仅是从运行队列中选择一个新进程,选择的过程中运用了不同的策略而已. 对于理解操作系统的工作机制,反而是进程的调 ...