有向图

实验 6:图的实验 1 -有向图的邻接表存储实现

匿名 (未验证) 提交于 2019-12-03 00:22:01
一、实验目的 1 2 3 二、实验内容 1、自己确定一个简单无向图(顶点数、和相关结点信息)利用邻接矩阵来实现存储。实现图的构造,并完成: 1) 用深度优先和广度优秀两种算法对图进行遍历,输出顶点序列数据; 2) 以合理的格式,输出各个顶点的邻接点; 2、试设计一个程序,对一个有向简单图,完成上题同样的任务 。 三、设计与编码 1.本实验用到的理论知识 (1)邻接表是顺序存储结构与链式存储结构相结合的存储方法,类似于树的孩子链表表示法; (2)在邻接表中涉及入度与出度,邻接与(到)的概念; (3)需要用结构体定义顶点表结点和边表结点。 2.算法与设计 (1)定义一个 ALGraph类 class ALGraph { public: ALGraph(char a[],int n,int e); //构造函数 ~ALGraph(); //析构函数 void DFSTraverse(int v); //深度优先遍历图 void BFSTraverse(int v); //广度优先遍历 void Print(char a [],int length); private: VertexNode adjlist[MaxSize]; //存放顶点表的数组 int vertexNum,arcNum; //图的顶点数和边数 }; 3.代码 #include<iostream.h> const int

【矩阵】将有向图转化为矩阵的应用

匿名 (未验证) 提交于 2019-12-03 00:21:02
给定一个有向图(可以有环),求从A点恰好走n步(可以重复经过边)到达B点的方案总数。 数据结构中学过图的邻接矩阵表示,m[i][j]=1表示存在有向边(i,j),m[i][j]=0表示不存在该边。 假设图有三个结点A,B,C。图的邻接矩阵表示为 A 1 0 1 B 0 0 1 C 1 1 1 求A到B恰好从2步的方案有: 方案总数恰好为图对应的矩阵m^2的第‘A’行第’B‘列的值。 当步数为n时,结论依然成立。 故只需求出图对应的矩阵,并用矩阵快速幂求出矩阵的n次幂后的矩阵即可。 文章来源: 【矩阵】将有向图转化为矩阵的应用

[Tarjan系列] Tarjan算法与有向图的SCC

£可爱£侵袭症+ 提交于 2019-12-02 23:49:23
前面的文章介绍了如何用Tarjan算法计算无向图中的e-DCC和v-DCC以及如何缩点。 本篇文章资料参考:李煜东《算法竞赛进阶指南》 这一篇我们讲如何用Tarjan算法求有向图的SCC( 强连通分量 )已经如何缩点。 给定一张有向图,若对于图中任意两个节点x和y, 既有x到y的路径,又有y到x的路径,则该有向图是一张“强连通图”。 有向图的极大连通子图被称为“强连通分量”,即SCC。 一个环一定是强连通图。如果既有x到y的路径,又有y到x的路径,那么x和y就一定在一个环中。 这就是Tarjan算法的原理:对于每个点x,找到与它一起能构成环的所有点。 下面介绍有向图中的三种边(x,y): 1. 树枝边:搜索树中x是y的父节点 2. 前向边:搜索树中x是y的祖先节点 3. 后向边:搜索树中y是x的祖先节点 4. 横叉边:除了以上三种情况外的边,满足dfn[y]<dfn[x] 这里只给出简单定义,不再赘述。 我们可以发现,用Tarjan算法求SCC时,后向边(x,y)可以和搜索树上从y到x的路径构成一个环。 除后向边外,通过横叉边也可能找到一条从y出发能回到x的祖先节点的路径。 那么为了找到通过横叉边和后向边构成的环,Tarjan算法在dfs的过程中维护一个栈,当访问到节点x时,栈中需要保存以下两类节点: 1. 搜索树上x的祖先节点,记为集合anc(x)。设y∈anc(x)

Codeforces 183C(有向图上的环长度)

匿名 (未验证) 提交于 2019-12-02 23:34:01
样例良心于是思路显然:就是求有向图(有自环有重边)上所有环长度的gcd。 get到求环长的方法: #include <cstdio> #include <cstring> #include <algorithm> #include <vector> using namespace std; const int maxn = 1e5 + 5; int n, m, ans; int val[maxn]; vector<int> adj[maxn], len[maxn]; bool vis[maxn]; int gcd(int a, int b) { if (!a || !b) return a + b;//ans初始为0所以有此写法 return gcd(b, a % b); } void dfs(int cur, int id) { vis[cur] = 1; val[cur] = id; for (int i = 0; i < adj[cur].size(); i++) { int son = adj[cur][i], l = len[cur][i]; if (!vis[son]) { dfs(son, id + l); } else if (val[son] != id + l) {//搜到过且不是上一个节点则为环 ans = gcd(ans, abs(id + l - val

有向图及深度广度遍历的简单实现

匿名 (未验证) 提交于 2019-12-02 23:34:01
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zgl390963305/article/details/90313058 有向图及深度广度遍历的简单实现 作者:Mrzhu007 日期:2019-05-18 博客地址: 金色世界 注:以最少代码实现各种经典数据结构,了解数据结构的魅力,以C++语言描述,不处理异常情况 如无说明,引用的均为C++标准库中STL组件 Graph数据定义 // 采用简单的矩阵实现有向图的数据结构定义 typedef std::vector<std::vector<int>> __Array; class CGraph { public: CGraph(int nSize_ = 0) : m_nNumVerter(nSize_), m_nNumEdge(0) { for(int _i = 0; _i < nSize_; ++_i) { std::vector<int> _temp; m_Data.push_back(_temp); for(int _j = 0; _j < nSize_;++_j) { m_Data.back().push_back(0); } } } ~CGraph() { } int NumberOfVertices() const { return m_nNumVertice; }

tarjan找有向图强连通分量

寵の児 提交于 2019-12-02 10:49:47
tarjan找强连通分量 有向图强连通分量 在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量。 tarjan找强连通算法 算法思想 首先,一个强连通分量形成一个环,或者是一个单点。 如何知道这个环上的某个点呢?即让这个点在dfs中被遍历到两次即可。 我们知道,图可以用dfs遍历,且dfs采用了“栈”的思想,可以用栈实现对强连通分量上的点的保存。一个点及其子孙中存在极大强连通分量,当且仅当该点是其与子孙各点中dfs序最小的那个,否则,若有一个子孙在它之前被遍历到,则能构成一个更大的强连通分量。 具体实现 变量定义 dfn[N]:某个点的dfs序 low[N]:某个点以及其子孙中dfs序最小的值 color[N]:某个点所属的强连通分量的颜色 st[N]:栈,用于储存可能构成强连通分量的点 vis[N]:某个点是否在栈中 代码 void tarjan(int u) { dfn[u]=low[u]=++deep; vis[u]=1; st[++top]=u; int sz=g[u].size(); for(int i=0;i<sz;i++) { int v=g[u][i

HNCPC2019H 有向图

让人想犯罪 __ 提交于 2019-12-02 02:10:09
题目 设 \(f_i\) 表示经过 \(i\) 的期望次数。那么显然答案 \(ans_j=\sum\limits_{i=1}^nf_iP_{i,j}\) 。 我们可以轻松地列出转移式子: \[ f_1=\sum\limits_{j=1}^nf_jP_{j,1}+1 \] \[ f_i=\sum\limits_{j=1}^nf_jP_{j,i} \] 高消即可。 #include<bits/stdc++.h> using namespace std; const int N=1007,P=1000000007; int p[N][N],a[N][N]; int inc(int a,int b){a+=b;return a>=P? a-P:a;} int mns(int a,int b){a-=b;return a<0? a+P:a;} int mul(int a,int b){return 1ll*a*b%P;} int inv(int a){int r=1,k=P-2;for(;k;k>>=1,a=mul(a,a))if(k&1)r=mul(a,r);return r;} int read(){int x;cin>>x;return x;} int main() { freopen("1.in","r",stdin); int n,m,i,j,k,x,ans,Inv=inv

Tarjan求有向图强连通分量 BY:优少

烂漫一生 提交于 2019-12-01 05:02:02
Tarjan算法:一种由Robert Tarjan提出的求解有向图强连通分量的线性时间的算法。 定义给出之后,让我们进入算法的学习。。。 【情境引入】 【 HAOI2006 受欢迎的牛】 题目描述: 每头奶牛都梦想成为牛棚里的明星。被所有奶牛喜欢的奶牛就是一头明星奶牛。所有奶 牛都是自恋狂,每头奶牛总是喜欢自己的。奶牛之间的“喜欢”是可以传递的——如果A喜 欢B,B喜欢C,那么A也喜欢C。牛栏里共有N 头奶牛,给定一些奶牛之间的爱慕关系,请你 算出有多少头奶牛可以当明星。 可以看出,当将每一个强连通分量视为每一个点时,受欢迎的奶牛只有可能是图中唯一的出度为零的点中的所有奶牛 这个时候,强连通分量的求得就出现了问题,这个时候,Tarjan算法应运而生 概念引入: 在有向图G中,如果两个顶点可以相互到达,则称两个顶点强连通。 如果有向图G的任意两个顶点都强连通,称G是一个强连通图。 非强连通有向图的极大强连通子图,称为强连通分量。 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达。{5},{6}也分别是两个强连通分量。 算法实现: Tarjan算法是基于对图深度优先搜索的算法。搜索时,把当前搜索树中未处理的节点加入一个堆栈,回溯时可以判断栈顶到栈中的节点是否为一个强连通分量。 相比看完这个莫名其妙的东西很少有人能理解,那就让我们进入具体讲解: 算法准备:

7. 图论

北城以北 提交于 2019-12-01 02:04:50
最短路 最小生成树 树的直径与最近公共祖先 基环树 负环与差分约束 Tarjan算法与无向图连通性 Tarjan算法与有向图连通性 二分图的匹配 二分图的覆盖于独立集 网络流初步 总结与练习 来源: https://www.cnblogs.com/hebust-fengyu/p/11647255.html

[Acwing#848.]有向图的拓扑序列

懵懂的女人 提交于 2019-11-30 10:19:45
题目来源: https://www.acwing.com/problem/content/description/850/ 给定一个n个点m条边的有向图,图中可能存在重边和自环。 请输出任意一个该有向图的拓扑序列,如果拓扑序列不存在,则输出-1。 若一个由图中所有点构成的序列A满足:对于图中的每条边(x, y),x在A中都出现在y之前,则称A是该图的一个拓扑序列。 输入格式 第一行包含两个整数n和m 接下来m行,每行包含两个整数x和y,表示点x和点y之间存在一条有向边(x, y)。 输出格式 共一行,如果存在拓扑序列,则输出拓扑序列。 否则输出-1。 数据范围 1≤n,m≤105 输入样例: 3 3 1 2 2 3 1 3 输出样例: 1 2 3 拓扑排序模板题,只需新建一个数组topu[]用来保存拓扑序列,需要注意的是自环也是环,有自环就不是DAG了。 #include <bits/stdc++.h> using namespace std; const int maxn = 1e5+1; vector<int> G[maxn]; int n, m, indg[maxn], topu[maxn]; void rd(){ scanf("%d %d", &n, &m); memset(indg, 0, sizeof(indg)); for(int i=1; i<=m; i++){