zoukankan      html  css  js  c++  java
  • C++图的欧拉路径搜索

    /*
     * description:        图的欧拉路径搜索
     * writeby:            Nick
     * date:            2012-10-25 23:32
     *
     */
    
    #include <iostream>
    #include <vector>
    #include <stack>
    
    using namespace std;
    
    struct Edge
    {
        int v, w;
        Edge(int v=-1, int w=-1) : v(v), w(w) {}
    };
    
    class Graph
    {
        private:
            int vcount, ecount;        //记录顶点总数,边总数
            bool digraph;            //标记是否有向图
            vector <vector <bool> > adj;        //邻接矩阵数组
        public:
            Graph(int V, bool di = false) : adj(V), vcount(V), digraph(di)
            {
                for(int i=0; i<V; i++)
                    adj[i].assign(V, false);    // V * V 临接矩阵的大小 
            }
            //~Graph();
            int V() const {return vcount;}
    
            int E() const {return ecount;}
    
            bool directed() const { return digraph; }
    
            int insert(Edge e)
            {
                int v=e.v, w=e.w;
                if(adj[v][w] == false) ecount++;
                adj[v][w] = true;                        // v-w 做标记
                if(!digraph) adj[w][v] = true;            //无向图中 w-v 也做标记
            }
    
            int remove(Edge e)
            {
                int v=e.v, w=e.w;
                if(adj[v][w]==true) ecount--;
                adj[v][w] = false;
                if(!digraph) adj[w][v] = false;
            }
    
            bool edge(int v, int w) const { return adj[v][w]; }
    
            class adjIterator;
            friend class adjIterator;
    };
    
    class Graph::adjIterator        //临接矩阵表示的迭代器
    {
        private:
            const Graph &G;
            int i, v;
        public:
            adjIterator(const Graph& G, int v) : G(G), v(v), i(-1)
            {}
    
            int begin()
            {
                i=-1;
                return next();
            }
    
            int next()
            {
                for(i++; i<G.V(); i++)
                    if(G.adj[v][i] == true) return i;    //adj[v][0..v-1] 记录着 v 到 0..v 各点是否相连
                return -1;    //没有找到
            }
    
            int end()
            {
                return i>=G.V();
            }
    };
    
    //描述图各顶点的度数的类
    class Degree
    {
        private:
            const Graph &G;
            vector <int> degree;
        public:
            Degree(const Graph &G) : G(G), degree(G.V(), 0)
            {
                for(int v=0; v<G.V(); v++)
                {
                    Graph::adjIterator ite(G, v);    //获取顶点v的遍历器
                    for(int w=ite.begin(); !ite.end(); w=ite.next())
                        degree[v]++ ;        //统计顶点的度数
                }
            }
            int operator[](int v) const
            {
                return degree[v];
            }
    };
    
    
    class epath
    {
        private:
            Graph G;
            int v,w;
            bool found;
    
            stack <int> S;
            int tour(int v);
        
        public:
            epath(const Graph &G, int v, int w) : G(G), v(v), w(w)
            {
                //查找欧拉路径基于
                //1.它是连通的,而且所有顶点都有偶数度数
                //2.它是连通的,而且只有两个顶点有奇数度数
    
                Degree deg(G);
                int t = deg[v] + deg[w];
                if(t%2 != 0) {found=false; return;} //顶点数要偶数, 或两个奇数
                for(t=0; t<G.V(); t++)
                    if((t!=v) && (t!=w))
                    {
                        if(deg[t]%2 != 0)
                        { found = false; return;}
                    }
                found = true;
            }
            bool exist() const { return found; }
    
            void show();    //输出路径
    };
    
    int epath::tour(int v)
    {
        while(true)
        {
            Graph::adjIterator ite(G, v);
            int w=ite.begin();
            if (ite.end()) break;
            S.push(v);
            G.remove(Edge(v, w));
            v=w;
        }
        return v;
    }
    
    void epath::show()
    {
        if(!found) return;
        while(tour(v) == v && !S.empty())
        {
            v = S.top();
            S.pop();
            cout << " - " << v;
        }
        cout << endl;
    }
    
    int main()
    {
        Graph g(7, false);
    
        g.insert(Edge(0, 1));
        g.insert(Edge(0, 2));
        g.insert(Edge(0, 5));
        g.insert(Edge(0, 6));
    
        g.insert(Edge(1, 2));
        g.insert(Edge(2, 3));
        g.insert(Edge(2, 4));
        g.insert(Edge(3, 4));
        g.insert(Edge(4, 5));
        g.insert(Edge(4, 6));
    
        epath sp(g, 1, 6);        //顶点1到6的欧拉路径
        cout << sp.exist() << endl;        //输出结果 0 或 1
        sp.show();
    
        return 0;
    }
  • 相关阅读:
    mysql5.7 ERROR 1045 (28000): Access denied for user解决方法
    C++ json解决方案
    Gitblit无法查看单个文件解决方案
    git 拉取指定的远程分支(三种方式)
    全栈12
    git commit之后,想撤销commit
    video
    iframe
    git恢复之前版本的两种方法reset、revert
    Eclipse
  • 原文地址:https://www.cnblogs.com/wouldguan/p/2741348.html
Copyright © 2011-2022 走看看