【説明する】一笔画
考试的方面:
(1)一笔画是怎样画的(水)
(2)能否实现一笔画(小技巧)
1)必须连通(有向与无向都必须满足)
2)有向图:(欧拉回路)如果出度等于入度,可以从任意点搜索;
(欧拉路)如果入度大于出度,则一定为终止点,而如果出度大于入度,则一定为开始的点(注意,如果入度与出度之间的差值大于一,则一定不能够形成欧拉路)
3)无向图:所有点的度数都为偶数时,才能实现欧拉回路||有两个点为奇数,且这两个点分别为起止点
一笔画性质:
■⒈凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为终点画完此图。
■⒉凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另一个奇点为终点。
■⒊其他情况的图都不能一笔画出。(奇点数除以二便可算出此图需几笔画成。)
求欧拉路的算法很简单,使用深度优先遍历即可。
根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找欧拉路,则对一个奇点执行DFS,时间复杂度为O(m+n),m为边数,n是点数。
l以下是寻找一个图的欧拉路的算法实现:
但是具有局限性,例如:
![](https://images2015.cnblogs.com/blog/1119446/201704/1119446-20170408203835847-1905286846.png)
还恳请大佬看到能够给出改进的意见,
这个代码可能有点啰嗦……
l样例输入:第一行n,m,有n个点,m条边,以下m行描述每条边连接的两点。
l 5 5
l 1 2
l 2 3
l 3 4
l 4 5
l 5 1
l样例输出:欧拉路或欧拉回路
l 1 5 4 3 2 1
代码~
#include<iostream> #include<cstdio> #include<string> #include<cstring> const int Maxn=1001; using namespace std; int g[Maxn][Maxn];//记录邻接顶点 int n,m;//n个点,m条边 int gs,start=1,p=0; /* gs用来统计不为偶数的个数, start用来寻找开始的点, p用来统计最终路线走过的点的个数 */ int du[Maxn];//记录每个的度 int road[Maxn];//记录路线 void findr(int i){ for(int j=1;j<=n;j++){ if(g[i][j]==1){ g[j][i]=g[i][j]=0;//消除关系,防止再次走 findr(j); } }road[++p]=i;//记录路线 } int main() { int a,b; scanf("%d%d",&n,&m); for(int i=1;i<=m;i++){ scanf("%d %d",&a,&b); g[a][b]=g[b][a]=1;//无向图 du[a]++; du[b]++; } for(int k=1;k<=n;k++){ if(du[k]%2!=0){ gs++; start=k;//拥有奇数个数,将start赋值为奇点坐标 } } if(gs==1||gs>2) { printf("Impossible!"); return 0; } else if(gs==2||gs==0)findr(start); for(int qwq=1;qwq<=p;qwq++){ printf("%d ",road[qwq]); }printf("\n"); return 0; }