zoukankan      html  css  js  c++  java
  • 欧拉回路

    //这是贴的;

    欧拉回路:图G,若存在一条路,经过G中每条边有且仅有一次,称这条路为欧拉路,如果存在一条回路经过G每条边有且仅有一次,

    称这条回路为欧拉回路。具有欧拉回路的图成为欧拉图。

    判断欧拉路是否存在的方法

    有向图:图连通,有一个顶点出度大入度1,有一个顶点入度大出度1,其余都是出度=入度。

    无向图:图连通,只有两个顶点是奇数度,其余都是偶数度的。

    判断欧拉回路是否存在的方法

    有向图:图连通,所有的顶点出度=入度。

    无向图:图连通,所有顶点都是偶数度。

    如下是判断欧拉回路是否存在的代码:

    #include <cstdio>
    #include <cstring>

    int set[1000 +10] , p[1000 +10];

    int find(int x){
    return set[x] == -1 ? x : find(set[x]);
    }

    int main(){
    int n , i , j , m;
    while(scanf("%d",&n),n){
    scanf("%d",&m);
    memset(p,0,sizeof p);
    for(i = 1 ; i <= n ; i ++)set[i] = -1;
    while(m--){
    int a,b,x,y;
    scanf("%d%d",&a,&b);
    x = find(a);
    y = find(b);
    if(x != y)set[a] = b;
    p[a]++;p[b]++;
    }
    int Q=0;
    for(i = 1; i <= n ; i ++){
    if(set[i] == -1)Q++;
    if(p[i]%2)Q++;
    }
    if(Q>1)puts("0");
    else puts("1");
    }
    }

    程序实现一般是如下过程:

    1.利用并查集判断图是否连通,即判断p[i] < 0的个数,如果大于1,说明不连通。

    2.根据出度入度个数,判断是否满足要求。

    3.利用dfs输出路径。

    比较好的题目是poj2337,判断单词是否连成一排的。

    hdu3018

    给出N个节点,M个边,问要遍历一遍所有的边,需要的最小group数目。
    求一个图中最少几笔画,利用欧拉回路性质,首先得到图的每个强连通分支,然后计算每个强连通分支每个是否都是偶数度是的话,一笔解决,否的话,需要奇数度节点个数的1/2笔解决。(当一个节点度数为奇数时,我们只需要令它的度数为1,因为偶数的话直接抵消了,最后判断一个scc中未1的节点个数,除以2就得到该scc的最小笔画了)

    poj1386

    给出n个单词,如果一个单词的尾和另一个单词的头字符相等,那么可以相连,问这n个单词是否可以排成一列。欧拉路应用,构图:一个单词的头尾字母分别作为顶点,每输入一个word,该word的头指向word的尾画一个有向边,并且记录每个顶点的出入度。利用并查集先判断是否为scc,如果是的话则判断是否奇数度节点为0或者只有2个。

    poj2230

    题目大意:给出n个field及m个连接field的边,然后要求遍历每条边仅且2次,求出一条路径来。
    这个题目典型欧拉回路,由于题目保证了肯定存在,所以我们直接dfs就行,首先有个小技巧是如何判断该条路是否走过了,也就是我们得对有向边进行标记。利用之前的结构
    struct edge{
        int next;
        int to;
    };
    edge node[maxm];
    int adj[maxv] = {-1}
    每一条边对应了一个next,我们只需要对next标记就可以了。

    poj2337
    求欧拉路径和poj1386同一个题,只不过这个题目需要输出欧拉路径。
    题目大意:给出一组单词,如果两个单词,一个单词的头和另一个单词的尾相同,则可以相连,例如abce, efdg,可以相连,问这组单词能否排成一排,如果可以求出字典序自小的那个。
    构图:单词作为边,单词的头字母和尾字母分别作为顶点,读入一个单词,添加一条边,并且用邻接表来存边,首先利用并查集判断图是否连通,然后再判断是否可以构成欧拉通路或者回路,如果是回路,则从a开始找,找到第一个存在的字母,从这个字母遍历就行,如果是通路,则必须从出度大于入度1的那个顶点开始遍历。由于这个题目要求最小字典顺序,然后考虑我们建立邻接表的时候是采用头插法,那么我们如果将单词从小到大排序,由于我们遍历顶点肯定是从小的顶点开始的,这样遍历一个顶点的邻接边的时候就会从大到小访问这个顶点的边,无法满足字典最小,所以从大到小排序,遍历依node数组为准,每次遍历一条边设置该下标已访问过。

  • 相关阅读:
    Linux共享wifi给Android手机
    史上最简单的Hibernate入门简单介绍
    TRIZ系列-创新原理-29-气动或液压结构原理
    使用GDI+进行图片处理时要注意的问题
    触发器系列(2) DataTrigger
    FizzBuzzWhizz问题python解法
    实现二值图像连通区标记之区域生长法
    《Java并发编程实战》第四章 对象的组合 读书笔记
    XCL-Charts画曲线图(CurveChart) 例2
    oracle中imp命令具体解释
  • 原文地址:https://www.cnblogs.com/newadi/p/3926980.html
Copyright © 2011-2022 走看看