• 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;
    }
  • 相关阅读:
    nginx-1.8.1的安装
    ElasticSearch 在3节点集群的启动
    The type java.lang.CharSequence cannot be resolved. It is indirectly referenced from required .class files
    sqoop导入导出对mysql再带数据库test能跑通用户自己建立的数据库则不行
    LeetCode 501. Find Mode in Binary Search Tree (找到二叉搜索树的众数)
    LeetCode 437. Path Sum III (路径之和之三)
    LeetCode 404. Sum of Left Leaves (左子叶之和)
    LeetCode 257. Binary Tree Paths (二叉树路径)
    LeetCode Questions List (LeetCode 问题列表)- Java Solutions
    LeetCode 561. Array Partition I (数组分隔之一)
  • 原文地址:https://www.cnblogs.com/wouldguan/p/2741348.html
Copyright © 2020-2023  润新知