无向图的欧拉路

如果从一个点出发,所有的边经过一次,则称为欧拉道路,如果最后回到了起点,那么成为欧拉回路

下面先讨论欧拉路的几个问题,最后给出每个问题的解决方案

下面给出两种情况的判定条件:

在所有边连通的情况下

如果所有的点的度数都为偶数,那么这是一条欧拉回路

如果存在两个奇度点,那么从一个奇度点出发,最后到达另一个奇点,则称这是一条欧拉道路

最后一个问题,就是打印欧拉路的路径方法,如果是欧拉回路的话,从任意一个存在边的点出发,那么最后都可以回到这个点

如果是欧拉道路,那么从一个奇点出发,到达另一个奇点

1.判断每一个点的度数问题

直接统计每个点的度数,最后统计是否存在奇数点就可以了,这个没什么问题

2.判断图的连通性

有两种方法,并查集和dfs

个人推荐并查集,每输入一条边,如果两个边不在同一个集合中,就将这个集合合并,下面给出代码

int f[205];
int find(int x){
    return f[x]==x?x:f[x]=find(f[x]);
}
//初始化并查集
void init(){
     for(int i=0;i<205;i++)//根据自己情况
        f[i]=i;
}

int u,v;
void read(){
    int n;
    cin>>n;
    for(int i=0;i<n;i++){
        cin>>u>>v;
        int x1=find(u);
        int x2=find(v);
        if(x1!=x2)
            f[x1]=f[x2];
    }
}
View Code

dfs判断连通也很容易,从一个节点出发,如果图是联通的,那么他可以走完所有的边,统计从一个点出发的边数就行了

//直接统计走过的边数也行,那么只要判断走过的边数是否和
void dfs(int u){
     for(int v=1; v <= 26; v++){
        if(map[u][v] ){
            map[u][v]--;
            dfs(v);
        }
    }
}
View Code

最后就是打印路径的方法

void euler(int u){

  for(int v=0;v<n;v++)

    if(map[u][v]&&!vis[u][v]){

      vis[u][v]=1;

      euler(v);

      printf("%d %d\n",u,v);

    }

}
View Code

如果是欧拉回路,开始选择任何一个点都可以,如果是欧拉道路,选择一个奇数点

 

posted @ 2016-03-29 21:24  N维解析几何  阅读(830)  评论(0编辑  收藏  举报