题目描述


样例呢?
我也不知道

task1/2

直接暴力就行了吧。。。

task3

因为m<=15,所以考虑状压dp
设f[t][i][s][0/1/2]表示当前跳跃t次,在第i个点,且走过的边状态为s(状压)时上一个可能的状态

有一个显然的性质,跳跃的次数肯定不会大于m
因为最坏的情况是每一条边跳到其中一个端点,然后再走一次

于是随便转移,时间复杂度O(m2n2m)O(m2n2m)O(m^2n2^m)(最坏情况)
最后反着输出方案

code

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
using namespace std;int a[200002][2];
int ls[100001];
int f[16][32768][16][3];
bool bz[16][32768][16];int p[16]={0,1,2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384};int n,m,i,j,k,l,x,y,len,L;void New(int x,int y)
{len++;a[len][0]=y;a[len][1]=ls[x];ls[x]=len;
}void dg(int x,int y,int z)
{if (!bz[f[x][y][z][0]][f[x][y][z][1]][f[x][y][z][2]]){printf("%d\n",z);return;}dg(f[x][y][z][0],f[x][y][z][1],f[x][y][z][2]);printf("%d %d\n",x-f[x][y][z][0],z);
}int main()
{freopen("miner.in","r",stdin);freopen("miner.out","w",stdout);scanf("%d%d",&n,&m);len=1;fo(i,1,m){scanf("%d%d",&x,&y);New(x,y);New(y,x);}if (n<=15 && m<=15){L=p[m]*2-1;fo(i,1,n)bz[0][0][i]=1;fo(i,0,m){fo(j,0,L-1){fo(k,1,n)if (bz[i][j][k]){for (l=ls[k]; l; l=a[l][1])if (!(j&p[l>>1])){int J=j|p[l>>1];if (!bz[i][J][a[l][0]]){bz[i][J][a[l][0]]=1;f[i][J][a[l][0]][0]=i;f[i][J][a[l][0]][1]=j;f[i][J][a[l][0]][2]=k;}}if (i<m){fo(l,1,n)if (!bz[i+1][j][l]){bz[i+1][j][l]=1;f[i+1][j][l][0]=i;f[i+1][j][l][1]=j;f[i+1][j][l][2]=k;}}}}}fo(i,0,m){fo(j,1,n)if (bz[i][L][j]){printf("%d\n",i);dg(i,L,j);return 0;}}return 0;}printf("0\n");//text5fclose(stdin);fclose(stdout);return 0;
}

task4

不知道

task5

因为

所以

    printf("0\n");

就有6分了(逃

咳咳
因为没有跳跃操作,所以直接在连通块里找欧拉路径(后来才发现其实不是回路)

欧拉回路/路径

来自百度

如果图G中的一个路径包括每个边恰好一次,则该路径称为欧拉路径(Euler path)。
如果一个回路是欧拉路径,则称为欧拉回路(Euler circuit)。

求欧拉回路有一种十分方便快捷的方法——Hierholzer算法
Hierholzer算法同样资瓷求欧拉路径(前提是要找一个合法的出发点)

设图中度数为奇数的点个数为x个,则
①x=0 任意点都可以
②x=2 在两个奇点中二选一
③x>2 无解


考虑最暴力的方法,每次不断dfs找经过所有边的路径
但是这样效率很低,因为可能会出现这样的情况:

从点1出发,沿着1-2-5-6-3-2的顺序去走

如果用普通的dfs,则需要退到5处,再走5-1-4-6-3-2,这样效率很低

但欧拉回路(好像)有个神奇的性质,就是当你选对一个点后,只要不走到死路提前去世,随便xjb走都可以走出一条路来

所以观察上面的路径,发现其实5-6-3-2可以放到后面去走,先走5-1-4-5

所以程序流程是:

对于当前点ufor (u,v)∈[E]删除 (u,v)删除 (v,u)递归v
把u加入答案集合

最后倒叙输出答案集合
思想和上面一样,如果走到死胡同就先放着,走完其它的边再走

代码比较简洁就不放了

于是这样就可以过text5了

task6

因为原图可能不连通,所以考虑分开一个个连通块来做
显然做完一个跳到另一个去做才是最优的

所以问题就变成处理每一个连通块
然而连通块内可能不能直接构成一个欧拉路径,必须要用卢本伟修改器来跳


有一个性质,一个无向图内奇数度数的点的个数x一定为偶数
采用反证法反正就是对的
如果x为奇数,则x*奇数度数+y*偶数度数=奇数
但在无向图中,每加一条边总度数就会+2
所以总度数一定为偶数,x必为偶数


因为x可能大于2,所以考虑用一条边把两个奇数度数的点连起来,这样等于做了一次1操作
那么就用最少的边把每个连通块变成x=0 or 2
之后随便搞搞欧拉回路久行了
(要开人工栈)

code

#include <iostream>
#include <cstdlib>
#include <cstdio>
#define fo(a,b,c) for (a=b; a<=c; a++)
#define fd(a,b,c) for (a=b; a>=c; a--)
#define max(a,b) (a>b?a:b)
using namespace std;int A[300011];
int a[300011][3];
int ls[100001];
int c[100001];
int b[100001];
bool bz[100001];
int g[100001];
int d[300001];
int D[300001];
bool Bz[300001];
int F[100001];
int fa[100001];
int n,m,i,j,k,l,x,y,len,ans,s,L,Len,II,next,t;int T[300001];
int I[300001];void New(int x,int y)
{len++;A[len]=x;a[len][0]=y;a[len][1]=ls[x];a[ls[x]][2]=len;ls[x]=len;
}int gf(int t)
{if (fa[t]==t)return t;fa[t]=gf(fa[t]);return fa[t];
}void del(int t)
{int pre=a[t][1],suc=a[t][2];Bz[t]=1;if (pre)a[pre][2]=suc;if (suc)a[suc][1]=pre;if (ls[A[t]]==t)ls[A[t]]=pre;
}void dfs(int t)
{int i;F[t]=II;if (b[t]&1){c[++L]=t;s++;}bz[t]=1;for (i=ls[t]; i; i=a[i][1])if (!bz[a[i][0]])dfs(a[i][0]);
}void Dfs(int tt)
{t=1;T[1]=tt;while (t){if (I[T[t]]){if (!Bz[I[T[t]]]){next=a[I[T[t]]][0];del(I[T[t]]);del(I[T[t]]^1);T[++t]=next;}elseI[T[t]]=a[I[T[t]]][1];}else{d[++Len]=T[t];while (g[T[t]])d[++Len]=T[t],g[T[t]]--;t--;I[T[t]]=a[I[T[t]]][1];}}
}int main()
{freopen("miner.in","r",stdin);freopen("miner.out","w",stdout);len=1;scanf("%d%d",&n,&m);fo(i,1,m){scanf("%d%d",&x,&y);if (x==y)g[x]++;elseNew(x,y),New(y,x);b[x]++;b[y]++;}fo(i,1,n)I[i]=ls[i];fo(i,1,n) fa[i]=i;fo(i,1,n)if (!bz[i] && b[i]){II=i;L=0;s=0;dfs(i);s>>=1;if (s)ans+=(s-1);ans++;for (j=3; j<=L; j+=2){New(c[j],c[j+1]);New(c[j+1],c[j]);I[c[j]]=ls[c[j]];I[c[j+1]]=ls[c[j+1]];fa[gf(c[j])]=gf(c[j+1]);}k=Len+1;if (L){Dfs(c[1]);fo(j,k+1,Len)if (d[j-1]!=d[j] && gf(d[j-1])==gf(d[j])){fa[d[j-1]]=d[j-1];fa[d[j]]=d[j];D[j]=1;}}elseDfs(i);}printf("%d\n",ans-1);printf("%d\n",d[1]);fo(i,2,Len)printf("%d %d\n",max(D[i],(F[d[i]]!=F[d[i-1]])),d[i]);fclose(stdin);fclose(stdout);return 0;
}

jzoj5840. Miner(欧拉路径)相关推荐

  1. [模板][持续更新]欧拉回路与欧拉路径浅析

    Luogu P2731 骑马修栅栏 Riding the Fences 题目背景 Farmer John每年有很多栅栏要修理.他总是骑着马穿过每一个栅栏并修复它破损的地方. 题目描述 John是一个与 ...

  2. 【图论专题】欧拉路径和欧拉回路

    A.AcWing 1123. 铲雪车(欧拉路的简单思想) 我们将这个图看成有向图,对于每输入一组数据加两条有向边,需要每条边都至少走一遍 我们先回想一下存在有向图的欧拉路径的充分必要条件 所有点的入度 ...

  3. poj 2513(欧拉路径+字典树映射)

    题目链接:http://poj.org/problem?id=2513 思路:题目还是很简单的,就是判断是否存在欧拉路径,我们给每个单词的头和尾映射序号,统计度数.对于给定的无向图,当且仅当图连通并且 ...

  4. 欧拉路径 之 poj 2513 Colored Sticks

    /* 欧拉路径 之 poj 2513 Colored Sticks欧拉路径: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径.无向图存在欧拉路径 充要条件:1) 图是连通的 ...

  5. POJ2337 欧拉路径字典序输出

    题意:       给一些单词,问是否可以每个单词只用一次,然后连接在一起(不一定要成环,能连接在一起就行). 思路:       这个题目的入手点比较好想,其实就是问欧拉路径,先说下解题步骤,然后在 ...

  6. Riding the Fences USACO 3.3 欧拉路径(dfs+floodfill)

    额,我是直接dfs的思路,但是到case 5过不去了,感觉是太慢了.然后网上看题解,题目原型就是欧拉路径, 欧拉路径存在的条件是 要么点的度都是偶数,要么只有两个点的度是奇数.如果是两个点的度是奇数, ...

  7. 图解Oracle 12c创建数据挖掘(Data Miner)用户dmuser

    主要参考文章 http://docs.oracle.com/cd/E11882_01/datamine.112/e16807/quickstart.htm#DMADM206 http://www.or ...

  8. CSP认证201512-4 送货[C++题解]:无向图欧拉路径、并查集、dfs

    题目分析 来源:acwing 分析: 无向图判断是否有欧拉路径:连通:度数为奇数的点,要么有2个,要么有0个. 如果有解,直接dfs求欧拉路径即可:只要有相连的边,就dfs遍历.当然,这里需要输出字典 ...

  9. 算法提高课-图论-欧拉回路和欧拉路径-AcWing 1185. 单词游戏:判断有向图是否存在欧拉路径、并查集

    文章目录 题目解答 题目来源 题目解答 来源:acwing 分析: 把每个单词看成一条边!!!首字母到尾字母的一条边,最多共有26个点(26个小写的英文字母),然后问能否把所有边串起来. 其实,对欧拉 ...

最新文章

  1. Keycloak Spring Security适配器的常用配置
  2. 娱乐:全方位戒除网瘾 如果你真的想告别WOW
  3. CSS3知识点整理(三)----变形与动画
  4. 偷懒大法好,用 selenium 做 web 端自动化测试
  5. Android添加单元测试的方法与步骤
  6. Application Transport Security has blocked a clear
  7. linux运行c程序a. out,无法运行已编译的文件 – bash:./ a.out:权限被拒绝. (我试过chmod)...
  8. Android 系统 (128)---ODM 开发用户常见需求文档(二)
  9. mysql 周 获取日期_MySQL获取日期周、月、天,生成序号
  10. 精译丨美国2017年最值得投资的7大共同基金
  11. 归并排序递归实现迭代实现
  12. 小米5 android7.1 root,小米MIUI 7 ROOT工具(supersu root) V5.1 最新安卓版
  13. PicGo搭建Gitee图库
  14. 按夏普计算机技巧,股票投资策略:怎样用夏普比率Sharpe Ratio寻找强势股
  15. S5P6818开发板移植OV5640摄像头
  16. jsp怎样写一个Button onclick事件
  17. VMware虚拟机不能识别U盘 的解决方法
  18. 真正的程序员到底应该是什么样子的?
  19. 如何生成高效、兼容性好的Poco定位脚本
  20. InstallShield 2010集成 net Framework 4的安装包制作

热门文章

  1. C语言 Mkl 矩阵乘法,使用MKL的Vector-Sparce矩阵乘法
  2. 基于Python的密码自助平台设计
  3. XSS(跨站脚本攻击) - 常用代码大全
  4. 小狗电器发布新品卧吸S9 AWE演绎碾压级最强吸力
  5. 网站公然叫卖用户账号密码 500元买百万条密码
  6. linux系统上传本地文件或文件夹
  7. 梦想CAD控件 2018.7.26更新
  8. 取水口取水监测计量、取水口取水量在线监测、取水在线监控
  9. 读《JavaServer Faces 核心编程(第3版)》一书的记录—— 第 6 章 数据库——案例 headersAndFooters
  10. P4994 终于结束的起点