#include<iostream>
#include<vector>
#include<stack>
#include<algorithm>
#include<set>using namespace std;/*
定义 N为图的节点数,E为边的数量(除去数组初始化)
步骤                  时间复杂度           空间复杂度
邻接矩阵                    O(E)                O(N*N)
关联矩阵                    O(E)                O(E*N)
强分图                 O(E)                O(E)
可达矩阵                    O(N*N)              O(N*N)
*///矩阵基类
class Matrix {protected:int**Data;int ColLength,RawLength;constexpr void SetValue(const int&col, const int&raw, const int&&val) {Data[col][raw] = val;}public:const int&GetColLength() { return this->ColLength; }const int&GetRawLength() { return this->RawLength; }Matrix(const int&Col, const int&Raw) :ColLength(Col), RawLength(Raw) {Data = new int*[Col + 1];for (int col = 1; col <= Col; ++col) {Data[col] = new int[Raw + 1];for (int raw = 1; raw <= Raw; ++raw) {Data[col][raw] = 0;}}}virtual void Output() {cout << '\t';for (int i = 1; i <= ColLength; ++i) {cout << 'v' << i << '\t';}cout << endl;for (int col = 1; col <= ColLength; ++col) {cout << 'v' << col << '\t';for (int raw = 1; raw <= RawLength; ++raw) {cout << Data[col][raw] << '\t';}cout << endl;}}~Matrix() {for (int i = 1; i <= ColLength; ++i) {delete[]Data[i];}delete[]Data;}
};//邻接矩阵
class AdjointMatrix :public Matrix {friend class StrongPartiteGraph;friend class ReachabilityMatrix;public:AdjointMatrix(const int&PointNumber) :Matrix(PointNumber, PointNumber) {  }void AddEdge(const int&from, const int&to) {this->SetValue(from, to, 1);}constexpr bool IsConnected(const int&from, const int&to) {return Data[from][to];}void Output()override {cout << '\t';for (int i = 1; i <= ColLength; ++i) {cout << 'v' << i << '\t';}cout << endl;for (int col = 1; col <= ColLength; ++col) {cout << 'v' << col << '\t';for (int raw = 1; raw <= RawLength; ++raw) {cout << Data[col][raw] << '\t';}cout << endl;}}AdjointMatrix*Clone() {AdjointMatrix*AM = new AdjointMatrix(this->ColLength);size_t&&Size = sizeof(int)*(ColLength + 1);for (int Index = 1; Index <= this->ColLength; ++Index) {memcpy(AM->Data[Index], this->Data[Index], Size);}return AM;}};//关联矩阵
class RelatedMatrix :public Matrix {public:RelatedMatrix(const int&PointNumber, const int&EdgeNumber) :Matrix(PointNumber, EdgeNumber) {  }void AddEdge(const int&EdgeIndex, const int&from, const int&to) {this->SetValue(from, EdgeIndex, 1);this->SetValue(to, EdgeIndex, -1);}void Output()override {cout << '\t';for (int i = 1; i <= RawLength; ++i) {cout << 'e' << i << '\t';}cout << endl;for (int col = 1; col <= ColLength; ++col) {cout << 'v' << col << '\t';for (int raw = 1; raw <= RawLength; ++raw) {cout << Data[col][raw] << '\t';}cout << endl;}}};//图
class Graph {vector<int>*G;struct Edge {const int from,to;Edge(const int&from, const int&to) :from(from), to(to) {  }};vector<Edge> Edges;int PointNumber;friend class StrongPartiteGraph;public:Graph(const int&N) :PointNumber(N) { G = new vector<int>[PointNumber + 1];}void AddEdge(const int&from, const int&to) {G[from].push_back(to);Edges.emplace_back(from, to);}AdjointMatrix* GetAdjointMatrix() {AdjointMatrix*M = new AdjointMatrix(PointNumber);for (int from = 1; from <= PointNumber; ++from) {for (const auto&to : G[from]) {M->AddEdge(from, to);}}return M;}RelatedMatrix* GetRelatedMatrix() {int&&EdgeNumber = 0;for (int from = 1; from <= PointNumber; ++from) {EdgeNumber += G[from].size();}RelatedMatrix*M = new RelatedMatrix(PointNumber, EdgeNumber);for (int Index = 0; Index < static_cast<int>(Edges.size()); ++Index) {M->AddEdge(Index + 1, Edges[Index].from, Edges[Index].to);}return M;}~Graph() {delete[] G;}};//并查集,用于算法优化
class DisjointSet {int MaxPoint;int *Father;public:DisjointSet(int MaxPoint) {this->Father = new int[MaxPoint + 1];for (int i = 1; i <= MaxPoint; ++i) {this->Father[i] = i;}}int Find(int x) {return this->Father[x] == x ? x : (this->Father[x] = Find(this->Father[x]));}void Merge(int x, int y) {this->Father[this->Find(x)] = this->Find(y);}bool isSameSet(int x, int y) {return Find(x) == Find(y);}~DisjointSet() {delete[]this->Father;}};//强分图,采用Gabow算法
class StrongPartiteGraph {vector<int> *G;AdjointMatrix*StrongPartiteMatrix;vector<int>*PointSet;vector<int>*StrongPartiteList;const int&PointNumber;int *Belongs,Color,*TimeTag,*Stack1,*Stack2;bool *Visable;void InitAdjointMatrix() {int&&CurrentSet = 1;this->PointSet = new vector<int>[Color + 1];this->StrongPartiteList = new vector<int>[Color + 1];this->StrongPartiteMatrix = new AdjointMatrix(Color);for (int Index = 1; Index <= PointNumber; ++Index) {this->PointSet[this->Belongs[Index]].push_back(Index);}DisjointSet DS(PointNumber);for (int Index = 1; Index <= Color; ++Index) {if (this->PointSet[Index].size() == 1)continue;auto it = this->PointSet[Index].begin();const int&temp = *(++it);for (; it != this->PointSet[Index].end(); ++it) {DS.Merge(*it, temp);}}for (int Index = 1; Index <= Color; ++Index) {for (const auto&Point : this->PointSet[Index]) {for (const auto&to : this->G[Point]) {if (!DS.isSameSet(Point, to)) {this->StrongPartiteMatrix->AddEdge(Index, this->Belongs[to]);if (Index != this->Belongs[to]) {this->StrongPartiteList[Index].push_back(this->Belongs[to]);}}}}}}void Visit(int cur, int&sig, int&scc_num){TimeTag[cur] = ++sig;Stack1[++Stack1[0]] = cur;Stack2[++Stack2[0]] = cur;for (const auto&to : this->G[cur]){if (!TimeTag[to]){Visit(to, sig, scc_num);}else if (!Belongs[to]){while (TimeTag[Stack2[Stack2[0]]] > TimeTag[to]) {--Stack2[0];}}}if (Stack2[Stack2[0]] == cur){--Stack2[0]; ++scc_num;do{Belongs[Stack1[Stack1[0]]] = scc_num;} while (Stack1[Stack1[0]--] != cur);}}void GabowCompute(){int sig;this->TimeTag = new int[PointNumber + 1];this->Stack1 = new int[PointNumber + 1];this->Stack2 = new int[PointNumber + 1];memset(this->Belongs, 0, sizeof(int)*(PointNumber + 1));memset(TimeTag, 0, sizeof(int)*(PointNumber + 1));sig = 0; Color = 0;Stack1[0] = 0; Stack2[0] = 0;for (int Point = 1; Point <= PointNumber; ++Point){if (!TimeTag[Point])Visit(Point, sig, Color);}delete[]this->TimeTag;delete[]this->Stack1;delete[]this->Stack2;this->InitAdjointMatrix();}public:StrongPartiteGraph(const Graph&G) :G(G.G), PointNumber(G.PointNumber) {this->Belongs = new int[PointNumber + 1];this->Visable = new bool[PointNumber + 1];memset(this->Belongs, 0x0, sizeof(int)*(PointNumber + 1));memset(this->Visable, 0x0, sizeof(bool)*(PointNumber + 1));this->GabowCompute();}AdjointMatrix*GetReachabilityMatrix() {AdjointMatrix*AM = new AdjointMatrix(PointNumber);int cnt = 0;auto Translate = [&AM,this](const int&FromSetIndex, const int&ToSetIndex)->void {for (const auto&from : this->PointSet[FromSetIndex]) {for (const auto&to : this->PointSet[ToSetIndex]) {AM->AddEdge(from, to); }}};bool**Vis = new bool*[PointNumber + 1];for (int Index = 1; Index <= PointNumber; ++Index) {Vis[Index] = new bool[PointNumber + 1];memset(Vis[Index], 0x0, sizeof(bool)*(PointNumber + 1));}stack<int>Stack;for (int Point = 1; Point <= Color; ++Point) {Stack.push(Point);vector<int>Froms;while (!Stack.empty()) {int from = Stack.top();Stack.pop();Froms.push_back(from);for (const auto&Precursor : Froms) {if (Vis[Precursor][from])break;Vis[Precursor][from] = true;Translate(Precursor, from);}for (const auto&to : this->StrongPartiteList[from]) {Stack.push(to);}}}for (int Index = 1; Index <= PointNumber; ++Index) {delete[]Vis[Index];}delete[]Vis;return AM;}void Output() {cout << "强分图共有" << Color << "个强连通分量" << endl<< "强分图为" << endl;this->StrongPartiteMatrix->Output();cout << "其中:" << endl;for (int Index = 1; Index <= Color; ++Index) {cout << "v" << Index << " = {";for (const auto&Point : this->PointSet[Index]) {cout << Point << ',';}cout << '\b' << '}' << endl;}}~StrongPartiteGraph() {delete[]this->Belongs;delete[]this->PointSet;delete this->StrongPartiteMatrix;delete[]this->Visable;}};int main() {int N;cout << "请输入点的数量N(编号从1到N):" << endl;cin >> N;Graph G(N);int M;cout << "请输入有向边的数量M:" << endl;cin >> M;cout << "依次输入有向边:" << endl<< "from\tto" << endl;while (M--) {int from, to;cin >> from >> to;G.AddEdge(from, to);}Matrix* matrix;cout << "邻接矩阵:" << endl;matrix = G.GetAdjointMatrix();matrix->Output();delete matrix;cout << "关联矩阵:" << endl;matrix = G.GetRelatedMatrix();matrix->Output();delete matrix;cout << "强分图:" << endl;StrongPartiteGraph SPG(G);SPG.Output();cout << "可达矩阵:" << endl;matrix = SPG.GetReachabilityMatrix();matrix->Output();delete matrix;system("pause");return 0;}

关于可达矩阵的O(N*N)算法和强分图的O(E)算法相关推荐

  1. matlab可达矩阵 结果,matlab求可达矩阵

    matlab中可达矩阵的计算 2页 1下载券 邻接矩阵的可达矩阵及层... 2页 2下载券 邻接矩阵的一种计算方法 7页 免费 ISM算法(邻接矩阵求可达... 暂无...... JAVA矩阵算法代码 ...

  2. WarShall算法求传递闭包(可达矩阵)

    最近在复习离散数学,顺便记录记录自己对warshall算法的理解. 1.传递闭包(可达矩阵) 传递闭包是有向图的一个重要性质,它指的是在有向图中从任意一个节点出发,可以到达的所有节点的集合.在某些应用 ...

  3. 达利欧利用计算机进行决策,瑞·达利欧谈AI:电脑算法很强 但它强不过人的思维...

    凤凰国际iMarkets讯(记者郑雨婷) 北京时间周二(2月27日),世界最大对冲基金桥水基金创始人瑞·达利欧(Ray Dalio)携新书<原则>来到中国,在由<财经>杂志独家 ...

  4. c++可达矩阵及连通性_3.9秒破百,矩阵式LED大灯加持,这台国产车可真香

    比亚迪汉,是继唐.宋.秦.元之后,第五款以我国历史朝代命名的比亚迪量产车,汉朝是继秦朝之后的大一统王朝,享国四百零七年.将这一伟大王朝作为全新车型的名称,它不仅是对繁华盛世的记载,更代表着对未来的向往 ...

  5. c++可达矩阵_测试分析人员必备知识—需求管理和可追溯性矩阵

    测试分析人员必备知识-需求管理和可追溯性矩阵 严格的软件开发过程的基石是需求管理以及这些需求对实施的可追溯性,以及随后对正确实施的证明. 需求可追溯性由作者Gotel和Finkelstein定义为&q ...

  6. 利用可达矩阵判断连通性_leetcode240. 搜索二维矩阵 II

    leetcode240. 搜索二维矩阵 II 编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target.该矩阵具有以下特性: 每行的元素从左到右升序排列. 每列的元素从上 ...

  7. 【有限马尔科夫链状态分解+Kosaraju 算法】基于Kosaraju 算法和可达矩阵的有限马尔科夫链状态分解

    有限马尔科夫链状态分解+Kosaraju 算法 1 实验内容 2 理论基础 3 题目分析 4 按常返性和互通性对状态空间进行分解算法流程 4.1 强连通性和强连通分量 4.2 基于有向图 Kosara ...

  8. 离散数学 —— 二元关系(图、零图与平凡图、度、握手定理、平行边、简单图与完全图、补图、子图与生成子图、同构、通路与回路、点与边割集、最短路线问题、强弱联通图、邻接矩阵与可达矩阵、欧拉图、平面图等)

    5.1     关系及其表示: 补充一点: 简单路径:无重复边(点不作要求) 基本路径(初级路径):无重复点 一个路径是基本路径,那么必是简单路径 5.2     路与回路: 5.3     图的矩阵 ...

  9. fota mcsync洛达检测_【科普篇】华强北洛达1536U芯片下的苹果Airpods,与正品差距还有多少...

    哈喽,大家好我是梵一潮品!评测之前,重要的事情要说三遍 华强北airpods距离正品还有差距!华强北airpods距离正品还有差距!华强北airpods距离正品还有差距! 但凡是哪个商家或者公众号测评 ...

  10. 【常见笔试面试算法题12续集二】动态规划算法案例2矩阵最小路径和练习题

    加qq1126137994 一起学习更多技术!!! 有一个矩阵map,它每个格子有一个权值.从左上角的格子开始每次只能向右或者向下走,最后到达右下角的位置,路径上所有的数字累加起来就是路径和,返回所有 ...

最新文章

  1. AI 崛起的第九个年头,还有哪些大有可为的地方?
  2. linux 终端管理工具,linux服务器-远程管理-screen:强大的终端管理工具
  3. Java 中的注解是如何工作的?
  4. NFV和VNF的现状如何
  5. PHP -----上传文件
  6. onvif_discover虚拟摄像头
  7. python统计行号_如何使用Python脚本分析CPU使用情况的?
  8. Ctrl与Caps Lock键的交换
  9. array_sum的用法
  10. django模板的使用方法
  11. LeetCode 4Sum 4个数之和
  12. 《Spring实战,【吐血整理】
  13. 201871010114-李岩松《面向对象程序设计(java)》第四周学习总结
  14. 为知笔记docker搭建
  15. Google野心勃勃,微软前程堪忧!(转)
  16. 水果店怎么开业吸引客户来,水果店新店开业如何吸引客人
  17. Milliman和Akur8结成战略联盟,为财产和意外伤害保险公司、管理型总代理和初创企业提供下一代定价能力
  18. DCloud的uniapp如何实现微信刷脸支付
  19. 【python】用turtle画七巧板
  20. 2020大学生网络安全知识大赛总决赛模拟卷错题集(10)

热门文章

  1. 计算机考研复试面试常问问题 数据结构篇(上)
  2. 2021-11-02 Kafka、Zookeeper的下载、打开、关闭
  3. 无标度网络 matlab,无标度网络及MATLAB建模
  4. PS-elevenday-铅笔工具(颜色替换)
  5. Tomcat安装及idea配置教程
  6. ffmpeg转码保留时间戳
  7. 分享6款国内、国外开源PHP轻论坛CMS程序
  8. pygame安装教程
  9. access查询出生日期格式转换_Access时间格式处理
  10. 量子通讯加密技术的技术原理