【説明する】一笔画

考试的方面:

(1)一笔画是怎样画的(水)

(2)能否实现一笔画(小技巧

1)必须连通(有向与无向都必须满足

2)有向图:(欧拉回路)如果出度等于入度,可以从任意点搜索;

(欧拉路)如果入度大于出度,则一定为终止点,而如果出度大于入度,则一定为开始的点(注意,如果入度与出度之间的差值大于一,则一定不能够形成欧拉路)

3)无向图:所有点的度数都为偶数时,才能实现欧拉回路||有两个点为奇数,且这两个点分别为起止点

一笔画性质:
■⒈凡是由偶点组成的连通图,一定可以一笔画成。画时可以把任一偶点为起点,最后一定能以这个点为终点画完此图。
■⒉凡是只有两个奇点的连通图(其余都为偶点),一定可以一笔画成。画时必须把一个奇点为起点,另一个奇点为终点。
■⒊其他情况的图都不能一笔画出。(奇点数除以二便可算出此图需几笔画成。)
  求欧拉路的算法很简单,使用深度优先遍历即可。
  根据一笔画的两个定理,如果寻找欧拉回路,对任意一个点执行深度优先遍历;找欧拉路,则对一个奇点执行DFS,时间复杂度为O(m+n),m为边数,n是点数。
l以下是寻找一个图的欧拉路的算法实现:
但是具有局限性,例如:

还恳请大佬看到能够给出改进的意见,

这个代码可能有点啰嗦……

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;
}

 

posted @ 2017-04-08 20:34  夜雨声不烦  阅读(276)  评论(0编辑  收藏  举报