欧拉路和欧拉圈,简言之就是,从无向图的一个结点出发,走一条路/圈,每条边恰好经过一次,即一笔画问题

欧拉定理:一个无向图最多只有两个奇结点,那么我们就从一个奇结点出发,到另一个结点为之,一定有一条欧拉路。

无向图:最多只能有两个奇节点的图则可判定为有欧拉路

有向图:最多只能有两个结点的入度和出度不相同,必须其中一个结点的入度比出度大1(终点),另一个结点的出度比入度大1(起点),且其无向图(即底图)是连通的。

应用:

  1. 判定欧拉路/圈的有无:根据底图的连通性+结点的度数判定,其中连通性的判定可使用DFS(见种子填充)或者并查集
  2. 如果有,构造欧拉路/圈:使用下面的代码:
 //用DFS构造欧拉路/圈
void euler(int u){
for(int v=;v<n;v++) if(G[u][v]&&!vis[u][v]){
vis[u][v]=vis[v][u]=;
euler(v);
printf("打印边:%d %d",u,v);
}
}

UVa中有一个类似的欧拉路的题目,涉及了复杂图的欧拉路的判定(有复边)

大意如下:给定N个单词(1<=N<=100000)判断能否构成词语接龙,即后一个单词的首字母与前一个单词的首字母一致。一个单词每出现一次就要考虑一次。详细的题目描述见传送门

传送门:UVa 10129

思路如下:

  1. 根据要求,我们要判定给定的N个单词能否构成词语接龙,那么我们只需要关注每个单词的开头字母和结尾字母。因此我们可以将每个单词看作从首字母到尾字母的一条边,那么词语接龙就是要在所给的有向图中找到一条欧拉路或者一个欧拉圈。
  2. 判定有向图的条件见上方:1.底图连通。2.节点的度数满足上述条件。
  3. 用并查集来判定底图的连通性(dfs真是烦),p数组用于存储并查集的代表元
  4. p数组存储的是边的节点的代表元,当所有节点的代表元都一致,说明底图连通
  5. 入度和出度分别使用in和out两个数组进行记录,用G作为记录边是否出现的map,每条边只计算一次即可,减少并查集的判别量。
  6. 除了判定欧拉路,也可能存在欧拉圈,因此代码中也判定了欧拉圈

代码如下:

 #include<cstdio>
#include<cstring> //memset()的定义
#include<iostream>
using namespace std; #define MAX 26 int G[MAX][MAX],m;//G存储图,m存储边的数量,用于并查集
int u[MAX*MAX],v[MAX*MAX],p[MAX]; //边i 的端点为u,v,p[x]是用于并查集的标记
int in[MAX],out[MAX]; //记录每个端点的入度和出度
int t,n;//题目中的t和n int char2int(char c){
return c-'a';
}
//Union Find Set
int find(int x){
return p[x]==x?x:p[x]=find(p[x]);
}
//判断以单词为图的连通性
bool isConnect(){
for(int i=;i<MAX;i++)p[i]=i;//初始化并查集
for(int i=;i<m;i++){ //按照边将端点的代表元进行合并
int x=find(u[i]),y=find(v[i]);
if(x!=y)p[x]=y;//Union 这样的Union使得连通性的判断实际上就是无向图的连通性的判断
}
int flag=find(u[]);//将第一个边的u端点作为代表检测元
for(int i=;i<m;i++)if(find(u[i])!=flag) return false;//如果出现了不同的代表元,则说明图不连通
return true;
}
bool hasStartEnd(){
int start=-,end=-;
for(int i=;i<MAX;i++){
if(end< && in[i]==out[i]+)end=i;
else if(start< && in[i]+==out[i])start=i;
else if(in[i]!=out[i])return false;//其他点如果入度和出度不相同,则不可能有欧拉路或者欧拉圈
}
return start==-&&end==- || start>=&&end>=;//两者同时为-1时是欧拉圈,同时大于等于0是欧拉路
}
bool hasEuler(){
if(n==)return true; //如果只有一个单词,那么肯定是可以得
return isConnect()&&hasStartEnd();//注意顺序不能反,从定义上不能反
}
int main(){
string s;
scanf("%d",&t);
while(t--){
scanf("%d",&n);
memset(G,,sizeof(G));m=;//初始化边的数目和图
memset(in,,sizeof(in));//初始化入度出度数组
memset(out,,sizeof(out));
while(n--){
cin>>s;
int u1=char2int(s[]),v1=char2int(s[s.length()-]);//顶点u和v
if(!G[u1][v1]){
u[m]=u1,v[m]=v1;//将边m的端点记录下来,便于使用并查集 ,也相当于初始化了边的端点集合
G[u1][v1]=;m++;//做判断是为了并查集的边数尽可能的小,所以用了if
}
in[v1]++,out[u1]++;
}
hasEuler()?puts("Ordering is possible."):puts("The door cannot be opened.");
}
}

 今天就到这里啦~欧拉路和欧拉圈就搞定啦~see you~(●'◡'●)

欧拉图和欧拉圈-Play On Words(UVa10129)的更多相关文章

  1. 欧拉图 欧拉回路 欧拉通路 Euler

    欧拉图 本文链接:http://www.cnblogs.com/Ash-ly/p/5397702.html 定义: 欧拉回路:图G的一个回路,如果恰通过图G的每一条边,则该回路称为欧拉回路,具有欧拉回 ...

  2. 欧拉图 欧拉回路 欧拉通路 Euler的认识 (转)

    转:https://www.cnblogs.com/Ash-ly/p/5397702.html 定义: 欧拉回路:图G的一个回路,如果恰通过图G的每一条边,则该回路称为欧拉回路,具有欧拉回路的图称为欧 ...

  3. SGU101 求有重边的无向图欧拉迹

    题意:好多木棒,俩端有数字(0--6)标记,按数字相同的端首尾相连成一条直线(木棒可以相同).即求有重边的无向图欧拉迹. 先判定是否为欧拉图,俩个条件,不说了.如果是欧拉图,输出路经. 方法:dfs遍 ...

  4. nyoj 42 一笔画 欧拉通路

    http://acm.nyist.net/JudgeOnline/problem.php?pid=42 一笔画问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 zyc ...

  5. The Best Path HDU - 5883 欧拉通路

    图(无向图或有向图)中恰好通过所有边一次且经过所有顶点的的通路成为欧拉通路,图中恰好通过所有边一次且经过所有顶点的回路称为欧拉回路,具有欧拉回路的图称为欧拉图,具有欧拉通路而无欧拉回路的图称为半欧拉图 ...

  6. hdu2588 GCD (欧拉函数)

    GCD 题意:输入N,M(2<=N<=1000000000, 1<=M<=N), 设1<=X<=N,求使gcd(X,N)>=M的X的个数.  (文末有题) 知 ...

  7. BZOJ 2705: [SDOI2012]Longge的问题 [欧拉函数]

    2705: [SDOI2012]Longge的问题 Time Limit: 3 Sec  Memory Limit: 128 MBSubmit: 2553  Solved: 1565[Submit][ ...

  8. BZOJ 2818: Gcd [欧拉函数 质数 线性筛]【学习笔记】

    2818: Gcd Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4436  Solved: 1957[Submit][Status][Discuss ...

  9. Euler-Maruyama discretization("欧拉-丸山"数值解法)

    欧拉法的来源 在数学和计算机科学中,欧拉方法(Euler method)命名自它的发明者莱昂哈德·欧拉,是一种一阶数值方法,用以对给定初值的常微分方程(即初值问题)求解.它是一种解决常微分方程数值积分 ...

随机推荐

  1. BZOJ4444 SCOI2015国旗计划(贪心+倍增)

    链上问题是一个经典的贪心.于是考虑破环成链,将链倍长.求出每个线段右边能作为后继的最远线段,然后倍增即可. #include<iostream> #include<cstdio> ...

  2. bug 跟蚊子的相似之处

    bug 跟蚊子的相似之处: 1.不知道藏在哪里. 2.不知道有多少. 3.总是在你即将睡觉休息的时候出现. 2 A:最近在看<一拳超人>,觉得咱们程序猿跟埼玉老师有点像啊! B:哪里像了? ...

  3. CF840C On the Bench 解题报告

    CF840C On the Bench 题意翻译 给定\(n\) \((1≤n≤300)\) 个数,求问有多少种排列方案使得任意两个相邻的数之积都不是完全平方数.由于方案数可能很大,输出方案数 \(m ...

  4. 洛谷 P3203 [HNOI2010]弹飞绵羊 解题报告

    P3203 [HNOI2010]弹飞绵羊 题目描述 某天,Lostmonkey发明了一种超级弹力装置,为了在他的绵羊朋友面前显摆,他邀请小绵羊一起玩个游戏.游戏一开始,Lostmonkey在地上沿着一 ...

  5. linux下搭建redis并解决无法连接redis的问题

    以前公司在开发阶段连接的redis一直是正式环境中的,最近老大让我在搭建一个局域网内的redis用于开发阶段时连接使用,搭建过程中也遇到了一些问题,还好已经解决了,在这里记录一下. 首先是搭建redi ...

  6. 解决导出为Excel时文件名乱码的问题。

    以前代码:public static void htmlToExcel(HttpContext context, string title, string html, string fileCss = ...

  7. POJ2391:Ombrophobic Bovines(最大流+Floyd+二分)

    Ombrophobic Bovines Time Limit: 1000MSMemory Limit: 65536K Total Submissions: 21660Accepted: 4658 题目 ...

  8. 【bzoj1597- [Usaco2008 Mar]土地购买】斜率优化

    [597][Usaco2008 Mar]土地购买 [题目描述] 有N (1 <= N <= 50,000) 块长方形的土地. 每块土地的长宽满足(1 <= 宽 <= 1,000 ...

  9. Python3中的Bytes和str之间的关系

    文本总是unicode字符集,用str类型表示. 二进制数据则由bytes表示.(通过socket在网络上传输数据时必须要用二进制格式)   Python不会以任何隐式的方式混用str和bytes,所 ...

  10. Hadoop安装过程

    1.安装JDK apt-get install openjdk-7-jdk 2.配置环境变量 vim /etc/profile 编辑: export JAVA_HOME=/usr/lib/jvm/ja ...