统计输出 图的环(c++ 有向加权图)
来源:互联网 发布:mac中如何切换输入法 编辑:程序博客网 时间:2024/06/06 18:52
构建图:
DiWeightGraph.h
#pragma once#include <memory>#include <fstream>#include <string>template <typename T>class DoCycle;template <typename T>class DiWeightGraph{public: class AdjacentcyList { public: class Edge { public: int v; int w; T weight; std::shared_ptr<Edge> next; public: Edge(const int& v, const int& w, const T& weight) :v(v), w(w), weight(weight), next(nullptr) { } int from()const { return v; } int to()const { return w; } }; class Iterator { private: std::shared_ptr<Edge> it; public: Iterator(const std::shared_ptr<Edge>& e) :it(e) { } Iterator operator ++() { if (it == nullptr) return *this; it = it->next; return *this; } bool operator !=(const Iterator& rhs)const { return it != rhs.it; } bool operator == (const Iterator& rhs)const { return it == rhs.it; } Edge operator *() { if (it == nullptr) throw std::out_of_range("* nullptr"); return *it; } }; std::shared_ptr<Edge> head; public: AdjacentcyList():head(nullptr) { } void addEdge(const Edge& e) { if (head == nullptr) { head = std::make_shared<Edge>(e); return; } std::shared_ptr<Edge> curr = head; while (curr->next != nullptr) { curr = curr->next; } curr->next = std::make_shared<Edge>(e); return; } Iterator begin()const { return Iterator(head); } Iterator end()const { return Iterator(nullptr); } };private: std::unique_ptr<AdjacentcyList[]> adj; int nV; int nE;public: DiWeightGraph(const std::string& file) { std::ifstream in(file); if (in.fail()) throw std::domain_error("文件打开失败\n"); in >> nV; adj = std::move(std::unique_ptr<AdjacentcyList[]>(new AdjacentcyList[nV])); while (!in.eof()) { int v, w; T weight; in >> v >> w >> weight; adj[v].addEdge(AdjacentcyList::Edge(v, w, weight)); ++nE; } } friend class DoCycle<T>;};
算法辅助友元类:
#pragma once#include "DiWeightGraph.h"#include <memory>#include <unordered_set>#include <stack>template <typename T>class DoCycle{ using Ed = typename DiWeightGraph<T>::AdjacentcyList::Edge; class Equal { public: Equal() { } bool operator()(std::stack<Ed> lhs,std::stack<Ed> rhs)const { while (!lhs.empty()) { int v1 = lhs.top().from(); if (rhs.empty()) return false; int v2 = rhs.top().from(); if (v1 != v2) return false; lhs.pop(); rhs.pop(); } if (!rhs.empty()) return false; return true; } }; class Hash { public: Hash() { } size_t operator ()(const std::stack<Ed>& sk)const { size_t ret = std::hash<T>()(sk.top().weight); return ret; } };private: bool iscycle; std::unique_ptr<bool[]> onStacked; std::unique_ptr<bool[]> marked; std::unordered_set<std::stack<Ed>,Hash,Equal> cycle; std::unique_ptr<std::shared_ptr<Ed>[]> edge;private: void init(DiWeightGraph<T> *dwg) { for (int i = 0; i < dwg->nV; ++i) { onStacked[i] = false; marked[i] = false; edge[i] = nullptr; } } void dfs(DiWeightGraph<T> *dwg,const int& s) { marked[s] = true; onStacked[s] = true; for (auto &e : dwg->adj[s]) { int w = e.to(); if (!onStacked[w]) { edge[w] = std::make_shared<Ed>(Ed(e.from(), e.to(), e.weight)); if (!marked[w]) dfs(dwg, w); } else { std::stack<Ed> sk; sk.push(Ed(e.from(), e.to(), e.weight)); for (std::shared_ptr<Ed> i = edge[s]; i != nullptr; i = edge[i->from()]) { sk.push(Ed(i->from(), i->to(), i->weight)); if (i->from() == w) break; } cycle.insert(sk); } } onStacked[s] = false; } void dfs(DiWeightGraph<T> *dwg) { for (int i = 0; i < dwg->nV; ++i) { init(dwg); dfs(dwg, i); } }public: DoCycle(DiWeightGraph<T> *dwg):onStacked(new bool[dwg->nV]),marked(new bool[dwg->nV]),edge(new std::shared_ptr<Ed>[dwg->nV]),iscycle(false) { dfs(dwg); if (!cycle.empty()) iscycle = true; } void display_cycle() { if (!iscycle) return; int i = 1; for (auto sk : cycle) { int loop = sk.top().from(); std::cout << "第" << i << "个环: "; while (!sk.empty()) { std::cout << sk.top().from() << "--> "; sk.pop(); } std::cout << loop << std::endl; ++i; } }};
main.cpp
#include <iostream>#include "DiWeightGraph.h"#include "DoCycle.h"using namespace std;int main(){ DiWeightGraph<double> dwg("test.txt"); DoCycle<double> dc(&dwg); dc.display_cycle(); system("pause"); return 0;}
test.txt
84 5 0.355 4 0.354 7 0.375 7 0.287 5 0.285 1 0.320 4 0.380 2 0.267 3 0.391 3 0.292 7 0.346 2 -1.203 6 0.526 0 -1.406 4 -1.25
运行:
阅读全文
1 0
- 统计输出 图的环(c++ 有向加权图)
- 有向加权图的深度优先遍历—C
- 图--加权有向图
- 有向加权图的邻接表实现
- 有向加权图的最短路径算法-Dijkstra
- 有向加权图的最短路径算法-Prim
- 加权无向图
- 加权无向图
- 算法——图之加权有向图
- Dijkstra最短路径算法(针对加权有向图)
- 5.五环加权有向图-最短路径问题
- 图--加权无向图
- 每日一省之————加权有向图的最短路径问题
- 输出有向图的环路(山债版)
- Java邻接表表示加权有向图,附dijkstra最短路径算法
- Java设计加权无向图
- C语言 - 统计输出的文字有多少个单词
- 判断有向图是否有环的C程序实现代码
- selenium 配合使用
- JDK8对并发的新支持
- docker应用-6(mysql+mycat 搭建数据库集群)
- mysql 导入 employees_db-full-1.0.6
- div内部滚动条滚动到底部和顶部
- 统计输出 图的环(c++ 有向加权图)
- CTF(信息安全夺旗赛)学习网址
- absolute、relative与float的学习
- iOS 延迟执行方法
- ubuntu安装了mysql 但是编译报错 mysql.h: No such file or directory
- 继承之重写(覆盖)父类方法的约束总结
- 树
- 2017NOMS全国运营峰会邀您同商互联网企业的商业化运营之路
- Maven如何导入jar包