有向图

20182301 2019-2020-1 《数据结构与面向对象程序设计》实验9报告

混江龙づ霸主 提交于 2019-12-07 09:13:34
20182301 2019-2020-1 《数据结构与面向对象程序设计》实验9报告 课程:《程序设计与数据结构》 班级: 1823 姓名: 赵沛凝 学号:20182301 实验教师:王志强 实验日期:2019年12月2日 必修/选修: 必修 1.实验内容 初始化:根据屏幕提示(例如:输入1为无向图,输入2为有向图)初始化无向图和有向图(可用邻接矩阵,也可用邻接表),图需要自己定义(顶点个数、边个数,建议先在草稿纸上画出图,然后再输入顶点和边数)(2分) 图的遍历:完成有向图和无向图的遍历(深度和广度优先遍历)(4分) 完成有向图的拓扑排序,并输出拓扑排序序列或者输出该图存在环(3分) 完成无向图的最小生成树(Prim算法或Kruscal算法均可),并输出(3分) 完成有向图的单源最短路径求解(迪杰斯特拉算法)(3分) 2. 实验过程及结果 初始化无向图和有向图: 有向图的建立算法 System.out.println("请按‘头节点 尾节点 回车’的形式依次输入边的信息"); for (int i=0;i<edgeNum;i++){ String preName = scan.next(); String folName = scan.next(); Vertex preV = getVertex(preName); Vertex folV = getVertex(folName)

tarjan有向图的强连通分量

旧城冷巷雨未停 提交于 2019-12-06 08:35:40
  有向图强 连通分量 :在 有向图 G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点 强连通 (strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个 强连通图 。有向图的极大强连通子图,称为强连通分量(strongly connected components)。   通过对强连通分量的缩点,可以将任意一个有向图变成一个有向无环图(DAG)。 我们将边分为四类:1.树枝边(x是y的父亲结点)2.前向边(x是y的祖先结点)3.后向边(x是y的子孙结点)4.横叉边(连向其他分支的并且已经搜过的边) 可以看出,树枝边是前向边的特殊情况。 如何判断x所在的位置在哪个强连通分量中? 情况1: 存在一条边后向边,指向祖宗结点。 情况2: 先由该点通过横叉边走到另一个分支,再由分支走到该点的某个祖宗结点上。 这里用tarjan算法求强连通分量。我们引入一个时间戳的概念,如上图,用dfs对其进行编号。 对每个点定义两个时间戳dfn[u]和low[u]表示从u开始走,所能遍历到的最小时间戳是什么。如果u是其所在的强联通分量重的最高点,等价于 dfn[u] == low[u] 。 可以证明,通过dfs搜图,能得到该图拓扑图的逆序,tarjan就是按照dfs的顺序搜索,所以

20182301 2019-2020-1 《数据结构与面向对象程序设计》第十周学习总结

白昼怎懂夜的黑 提交于 2019-12-05 15:33:13
20182301 2019-2020-1 《数据结构与面向对象程序设计》第十周学习总结 教材学习内容总结 图的结构构成 顶点(vertex):图中的数据元素,如图一 边(edge):图中连接这些顶点的线,如图一 G=(V,E) 或者 G=(V(G),E(G)) 其中 V(G)表示图结构所有顶点的集合,顶点可以用不同的数字或者字母来表示。E(G)是图结构中所有边的集合,每条边由所连接的两个顶点来表示。 图结构中顶点集合V(G)不能为空,必须包含一个顶点,而图结构边集合可以为空,表示没有边。 图的基本概念 无向图 如果一个图结构中,所有的边都没有方向性,那么这种图便称为无向图。典型的无向图,如图二所示。由于无向图中的边没有方向性,这样我们在表示边的时候对两个顶点的顺序没有要求。例如顶点VI和顶点V5之间的边,可以表示为(V2, V6),也可以表示为(V6,V2)。 有向图 一个图结构中,边是有方向性的,那么这种图就称为有向图,如图三所示。由于图的边有方向性,我们在表示边的时候对两个顶点的顺序就有要求。我们采用尖括号表示有向边,例如<V2,V6>表示从顶点V2到顶点V6,而<V6,V2>表示顶点V6到顶点V2。 顶点的度 连接顶点的边的数量称为该顶点的度。顶点的度在有向图和无向图中具有不同的表示。对于无向图,一个顶点V的度比较简单,其是连接该顶点的边的数量,记为D(V)。

关于有向图走“无限次”后求概率/期望的口胡/【题解】HNCPC2019H 有向图

╄→гoц情女王★ 提交于 2019-12-04 09:24:17
关于有向图走“无限次”后求概率/期望的口胡/【题解】HNCPC2019H 有向图 全是口胡 假了不管 讨论的都是图 \(G=(V,E),|V|=n,|E|=m\) 上的情况 “走无限次”这个概念很抽象,严谨的证明以及描述和概率的收敛性有关, 由于我也不会 在此就不讨论这些,但是根据一些概率的知识,可以发现,其实走无限次可以这样描述: 由于使用概率不好描述在无限次的情况时,每个点和点之间的关系,所以用期望。到时候根据期望的定义式反过来求概率。可能的问题是,“不是走无限次吗,那怎么用期望反过来求概率?”。举个例子,假若只有一个起点,那么所有随机变量 \(X=1\) ,所以 \(E(X)=XP(X)=P(X)\) 。 这是因为期望可以很方便的描述点与点之间的关系(用概率的话,不好描述走无限次的“过程”,在从0次走到无穷次的途中的关系不好用概率描述(因为概率是一个相乘的关系,而期望是相乘且求和(概率不也是吗?我也不知道我在说什么,可能这段话是强行解释,因为我做的题都是用这个得到初始条件的))) 设 \(e=[f_i\dots]\) 是 \(i\) 点的期望构成的行向量,至于我们如何定义“i点的期望”,具体问题具体分析。 设矩阵 \(A_{n\times n}\) 是“增广矩阵”(我xjb取的名字),其中 \(A_{i,j}\) 表示由 \(i\) 点转移到 \(j\) 点的概率

AcWing 848. 有向图的拓扑序列

时光怂恿深爱的人放手 提交于 2019-12-04 04:43:50
模拟队列 #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 100010; int n, m; int h[N], e[N], ne[N], idx;//邻接表 int d[N];//入度 int q[N];//队列 void add(int a, int b) { e[idx] = b, ne[idx] = h[a], h[a] = idx ++ ; } bool topsort() { int hh = 0, tt = -1; for (int i = 1; i <= n; i ++ ) if (!d[i])//先把所有入度为0的点插入到队列 q[ ++ tt] = i;//进入队列 while (hh <= tt) { int t = q[hh ++ ];//取出进度为0 for (int i = h[t]; i != -1; i = ne[i]) {//所有和i相连的点,也就是和入度为0的点相连的点 //入度都要减一 int j = e[i]; //找到出边 d[j]--;//让入度减,也就是把出边剪掉 if (d[j] == 0)//当进度减为0,进入队列 q[ ++ tt] = j; } } return tt == n - 1;/

数据结构之图的基本概念

╄→гoц情女王★ 提交于 2019-12-04 03:41:23
一 图的定义 定义:图(Graph)是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G(V,E),其中,G表示一个图,V是图G中顶点的集合,E是图G中边的集合。   在图中需要注意的是:   (1)线性表中我们把数据元素叫元素,树中将数据元素叫结点,在图中数据元素,我们则称之为顶点(Vertex)。   (2)线性表可以没有元素,称为空表;树中可以没有节点,称为空树;但是,在图中不允许没有顶点(有穷非空性)。   (3)线性表中的各元素是线性关系,树中的各元素是层次关系,而图中各顶点的关系是用边来表示(边集可以为空)。 二 图的基本概念 (1)无向图 如果图中任意两个顶点之间的边都是无向边(简而言之就是没有方向的边),则称该图为无向图(Undirected graphs)。 (2)有向图 如果图中任意两个顶点之间的边都是有向边(简而言之就是有方向的边),则称该图为有向图(Directed graphs)。 (3)完全图 ①无向完全图:在无向图中,如果任意两个顶点之间都存在边,则称该图为无向完全图。(含有n个顶点的无向完全图有(n×(n-1))/2条边)如下图所示: ②有向完全图:在有向图中,如果任意两个顶点之间都存在方向互为相反的两条弧,则称该图为有向完全图。(含有n个顶点的有向完全图有n×(n-1)条边)如下图所示: PS:当一个图接近完全图时,则称它为稠密图

图论 - 概念

蓝咒 提交于 2019-12-04 01:58:27
无序对: 对于二元集合{a,b},由于元素之间没有次序,称{a,b}为无序对,记为(a,b)。 有序对: 由两个元素x和y(允许x=y)按一定顺序排列成的二元组叫做一个有序对,记作<x,y>,其中x是它的第一元素,y是它的第二元素。 无序积: 设A,B为集合,则称{(a,b)| a∈A∧b∈B}为A与B的无序积,记为A&B。 恒有A&B=B&A。 笛卡尔积: 设A,B是任意两个集合,用A中元素作第一元素,B中元素作第二元素,构成的有序对,所有这样有序对的全体组成的集合称集合A和B的笛卡儿积,记作A×B。 顶点集: 非空集合V={v1,v2,…,vn},称为 图G 的顶点集(vertexset)V中元素称为顶点。 无向边: 是无序积V&V的一个多重子集E={e1,e2,…,en},称为的边集(edge set),E中的元素称为无向边,简称边。 无向图: 一个无向图是一个有序的二元组<V,E>,记作G, 即G=<V,E>。 每条边都是无向边的图称为无向图。 有向边: E为边集,是笛卡儿积V×V的多重子集,其元素称为有向边,简称边。 有向图: 一个有向图是一个有序的二元组<V,E>,记作D, 即D=<V,E>。 每条边都是有向边的图称为有向图。 基图: 将有向图各有向边均改成无向边后得到的无向图 称为原来有向图的基图(underlying graph)。 端点: 图G中的边e k

图神经网络(GNN)系列

僤鯓⒐⒋嵵緔 提交于 2019-12-03 23:53:16
https://www.toutiao.com/a6657069801371861518/ 2019-02-12 19:10:46 真实世界中,许多重要的数据集都是以图或者网络的形式存在的,比如社交网络,知识图谱,蛋白质相互作用网,世界贸易网等等。然而,迄今为止,却很少有人关注并且尝试将神经网络一般化后应用在这样的数据集上,而现在深度学习在人工智能领域大形其道,如果能够将神经网络和图分析进行结合,将会解决许多的问题,本文中重点介绍在图神经网络中的两个很重要的算法DeepWalk and GraphSage. Graph结构 图结构是计算机中很重要的一个数据结构,一个图结构包括两个部分: 顶点(node)和边(edge),即表示的形式是: 图分为有向图和无向图, 有向图是边上带有方向,表示两顶点的依赖是有方向性的,如图所示 图神经网络 来源: CSDN 作者: 喜欢打酱油的老鸟 链接: https://blog.csdn.net/weixin_42137700/article/details/87159371

AcWing848 有向图的拓扑序列

百般思念 提交于 2019-12-03 15:25:51
给定一个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 一道拓扑排序的模板题。拓扑排序的算法是,首先找到入度为0的点(所以需要一个数组 to[] 维护每个结点的入度),将它放入队列,然后依次枚举它的所有出边 t->j ,删掉它们之间的连接 to[j]-- ,如果此时 to[j]==0 ,那么将 j 入队,持续这个过程直到队列为空。 代码: #include <iostream> #include <queue> #include <memory.h> using namespace std; const int N = 1e5+10; int h[N], e[N], ne[N], idx; int to[N], ans[N]; int n, m; void add(int a, int b){ e[idx] =

拓扑排序判断有向图是否成环

匿名 (未验证) 提交于 2019-12-03 00:27:02
#include <cstdio> #include <cstring> #include<iostream> #include <queue> using namespace std; const int maxn = 1e5 + 7; int n,m, du[maxn], head[maxn], tot,cnt,ans[maxn]; struct node { int v, next; } edge[maxn]; queue<int>q; void add(int u, int v) { edge[tot].v = v; edge[tot].next = head[u]; head[u] = tot++; } void init() { tot = 0; memset(du, 0, sizeof(du)); memset(head, -1, sizeof(head)); } void solve() { while(!q.empty()) { int u = q.front(); q.pop(); ans[cnt++]=u; for (int i = head[u] ; i != -1 ; i = edge[i].next) { du[edge[i].v]--; if (!du[edge[i].v]) q.push(edge[i].v); } } } int main() {