fortran迭代欧拉算法_Hierholzer 算法应用举例

点击上方“蓝字”,发现更多精彩。背景

f8bfe57f84638b71b4cdcece583ee163.png

01PART解题思路本题本质即为不重复的遍历完图中的所有边,即 “只一笔描完图中所有边,且不重复”。①.首先把图的边缘列表转成邻接列表,以方便遍历每个节点的每条边。②.用状态标记每条边是否走过,可以避免对容器进行插入\删除元素时出现迭代器失效问题。③.map 默认是按字典升序排序。④.使用 DFS 遍历所有边,遍历到底不符合要求则撤销当前状态。02PART代码示例
class Solution {public:    unordered_map<string,map<string,int>> tickmp;// 出发地---[目的地---剩余票数]    int tickCount;//票的总数    vector<string> res;//保存结果    vector<string> findItinerary(vector<vector<string>>& tickets) {        tickCount = tickets.size();//初始化票总数        //初始化邻接列表        for( int i = 0;i < tickets.size();i++)        {            //  A --> B            string A = tickets[i][0];            string B = tickets[i][1];            tickmp[A][B]++;        }        res.push_back("JFK");        dfs("JFK");        return res;    }    //检查从一个起点出发是否还有票    bool chekHazDes( const string &fromStr){        if( tickmp[fromStr].size() == 0) return false;        for( auto it = tickmp[fromStr].begin();it != tickmp[fromStr].end();++it)        {            if( it->second > 0)                return true;        }        return false;    }    bool dfs(const string &fromStr){        if( tickmp.find(fromStr) == tickmp.end() || !chekHazDes(fromStr))//没有可选的目的地了        {            if( tickCount == 0)//所有票用完了                return true;            else                return false;        }        //遍历当前能做的所有选择、依次选择从当前起点出发的每一张票        for( auto it = tickmp[fromStr].begin();it != tickmp[fromStr].end();++it )        {            if( it->second == 0)//该票已经用过                continue;            string toStr = it->first;//目的地            res.push_back(toStr);//加入到结果            --tickCount;//剩余票数减一            it->second--;//当前起点与目的地的票数减一            bool isok = dfs(toStr);            if( isok ) return true;            else            {                //撤销上次结果                it->second++;                ++tickCount;                res.pop_back();            }        }        return false;    }};
Hierholzer算法01PART基本概念

①.欧拉路径:如果在一张图中,可以从一点出发遍历所有的边,那么遍历过程中的这条路径就叫做欧拉路径。

②.欧拉回路:如果欧拉路径是闭合的,则成为欧拉回路。

③.欧拉图:具有欧拉回路的图。

④.半欧拉图:有欧拉路径但没有欧拉回路的图称为半欧拉图。

无向图中,如果所有顶点的度数都为偶数,则为欧拉图;如果有两个顶点的度数为奇数,其他的为偶数,则为半欧拉图。 有向图中,如果所有顶点的入度等于出度,那么就是欧拉图。如果恰有一个顶点出度和入度差为 1 且其他顶点的入度和出度相同,则为半欧拉图。02PART算法步骤

Hierholzer 算法的一般过程为:

①.选择任一顶点为起点,遍历所有相邻边。

②.深度搜索,访问相邻顶点。将经过的边都删除。

③.如果当前顶点没有相邻边,则将顶点入栈。

④.栈中的顶点倒序输出,就是从起点出发的欧拉回路。

03PART代码示例
class Solution {public:    unordered_map<string, priority_queue<string, vector<string>, std::greater<string>>> vec;    vector<string> stk;    void dfs(const string& curr) {        while (vec.count(curr) && vec[curr].size() > 0) {            string tmp = vec[curr].top();            vec[curr].pop();            dfs(move(tmp));        }        stk.emplace_back(curr);    }    vector<string> findItinerary(vector<vector<string>>& tickets) {        for (auto& it : tickets) {            vec[it[0]].emplace(it[1]);        }        dfs("JFK");        reverse(stk.begin(), stk.end());        return stk;    }};
c76817f27e3897ffe663f70c42449858.png扫码关注持续获取最新文章c++学习 算法与数据结构
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值