BZOJ3724 PA2014Final Krolestwo(欧拉回路+构造)
如果没有长度为偶数的限制,新建一个点向所有奇点连边,跑欧拉回路即可,显然此时一定存在欧拉回路,因为所有点度数都为偶数。
考虑长度为偶数的限制,将每个点拆成两个点放进一个二分图里,那么每条原图中的边在二分图中会对应两条边,一条长度为偶数的路径在二分图中显然是由某部分出发再走回这部分。我们需要让每条原图中的边恰在二分图中出现一次,且保证所有点度数为偶数,这样仍然跑个欧拉回路就完了。
对原图任意取一棵生成树。让非树边任意连,然后通过树边调整度数以达到目的。注意到新建点并连边后,原图中所有点度数都为偶数,而原图中的点在二分图中的对应两点度数之和,就是该点在原图中的度数,也即偶数。也就是说任意点的对应两点度数奇偶性相同,调整一条与其相连的边会同时改变这两点的度数奇偶性。于是考虑怎么调整树边,自底向上,如果某点的儿子当前不满足条件,就改变这条边的连接方式,显然这样儿子的度数就合法了。不断调整上去,最后只剩下根,不过事实上根此时已经合法,因为边的总数是偶数,二分图某边的点度数之和也是偶数,不可能只有根的度数是奇数。
悲惨地发现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(欧拉回路+构造)的更多相关文章
- BZOJ3724PA2014Final Krolestwo——欧拉回路+构造
题目描述 你有一个无向连通图,边的总数为偶数.设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每条边长度为1)的 ...
- hdu 4850 字符串构造---欧拉回路构造序列 递归+非递归实现
http://acm.hdu.edu.cn/showproblem.php? pid=4850 题意:构造长度为n的字符序列.使得>=4的子串仅仅出现一次 事实上最长仅仅能构造出来26^4+4- ...
- 【刷题】BZOJ 3724 PA2014Final Krolestwo
Description 你有一个无向连通图,边的总数为偶数. 设图中有k个奇点(度数为奇数的点),你需要把它们配成k/2个点对(显然k被2整除).对于每个点对(u,v),你需要用一条长度为偶数(假设每 ...
- CF36E Two Paths (欧拉回路+构造)
题面传送门 题目大意:给你一张可能有重边的不保证联通的无向图,现在要在这个图上找出两条路径,恰好能覆盖所有边一次,根据边的编号输出方案,无解输出-1 一道很不错的欧拉路径变形题 首先要知道关于欧拉路径 ...
- @bzoj - 3724@ PA2014Final Krolestwo
目录 @description@ @solution@ @accepted code@ @details@ @description@ 你有一个无向连通图,边的总数为偶数. 设图中有k个奇点(度数为奇 ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- NOI前训练日记
向别人学习一波,记点流水帐.17.5.29开坑. 5.29 早晨看了道据说是树状数组优化DP的题(hdu5542),然后脑补了一个复杂度500^3的meet in the middle.然后死T... ...
- IOI 2020 集训队作业胡扯
首先安慰自己:做的没集训队快很正常-- 很正常-- 做不完也很正常-- 很正常-- 全都不会做也很正常-- 很正常-- 表格 试题一 完成情况 试题二 完成情况 试题三 完成情况 cf549E cf6 ...
- 2015多校.MZL's endless loop(欧拉回路的机智应用 || 构造)
MZL's endless loop Time Limit: 3000/1500 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Oth ...
随机推荐
- Android学习之基础知识五—编写聊天界面
第一步:在app/build.grandle添加RecyclerView依赖库 第二步:在activity_main.xml文件中编写主界面:聊天.发送框.发送按钮三个部分 第三步:编写Message ...
- java 二维数组和对象数组
1.二维数组:二维数组就是存储一维数组(内存地址/引用)的数组 2.二维数组的初始化 1) int intA[][]={{1,2},{2,3},{3,4,5}}; 2) int [][] intB=n ...
- Java字节码里的invoke操作&&编译时的静态绑定与动态绑定
一个一直运行正常的应用突然无法运行了.在类库被更新之后,返回下面的错误. Exception in thread "main" java.lang.NoSuchMethodErro ...
- B Long Path
有n+1个房间.从1-n个房间.每个房间有两扇门.一扇去i+1的房间另一扇去编号为pi的房间. 起点为1,终点为n+1,对应第i个各点,如果我奇数次到达,那么下一步走到a[i]的位子,如果是偶数次到达 ...
- PowerDesign 16.0 生成的SQL Server2000 数据库脚本时MS_Description不存在的问题解决
根据网上查询到的资料,找到了解决方法,原文出自:http://www.cnblogs.com/24tt/p/5047257.html PowerDesign 16.0 生成的Script语句,Sql2 ...
- css-文本左右对齐
1.给目标元素加 display:block;text-align:justify; 2.如果最后一行没充满整行,因为text-align:justify,所以字字之间会有间隔,应给目标元素加伪类,添 ...
- 计算机网络什么是OSI7层模型、TCP/IP4层模型理解
模型图解 应用层 就是最顶层的.通常指的应用程序初始走的协议比如有 TFTP,HTTP,SNMP,FTP,SMTP,DNS,Telnet 表示层 主要对数据应用层的数据包进行加密 会话层 建立.管理. ...
- webvirtmgr-重命名kvm虚拟机的名称
之前部署了Webvirtmgr平台管理kvm虚拟机,由于虚拟机在创建时名称是顺便起的,后续在虚拟机上部署了部分业务.为了便于管理,最好将虚拟机的名称重置下. 现在说下如何修改kvm中虚拟机的名称: 比 ...
- 索引节点(inode)爆满问题处理
关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享几个情况: 情况一 在公司一台配置较低的Linux服务器(内存.硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h命 ...
- 硬编码转换单位||vue
//测试单位 formatUnit:function (id) { var val; switch(id){ case 4: return val="圈" break; } } / ...