图论算法

【ACM算法】-- 图论篇 - 最小生成树(MST)

青春壹個敷衍的年華 提交于 2020-03-03 00:20:32
第一题: 这里讨论最小生成树问题,最小生成树是原图的一个子图,其中包含所有节点,仅含有部分边,使得这个子图为连通图,且不含有环路,并且边上的权值和最小,则称为最小生成树。 思路: 这道题用克鲁斯卡尔的方法来求最小生成树: 如上图:我们需要两种数据结构,一个是用来确定两个点是否属于一个集合,另一个是我们要将边的权值进行排序,需要一个struct来存储边,并且用到了重载小于号,使用sort快排。 代码如下: # include <stdio.h> # include <algorithm> using namespace std ; # define N 101 int Tree [ N ] ; int findRoot ( int x ) { if ( Tree [ x ] == - 1 ) return x ; else { int tmp = findRoot ( Tree [ x ] ) ; Tree [ x ] = tmp ; return tmp ; } } struct Edge { int a , b ; int cost ; bool operator < ( const Edge & A ) const { return cost < A . cost ; } } edge [ 6000 ] ; int main ( ) { int n ; freopen (

【图论】最小生成树算法(prim和kruskal详解及对比)

心已入冬 提交于 2020-03-02 10:32:06
目录 一.最小生成树之 p r i m prim p r i m 算法 p r i m prim p r i m 完整代码(计算最短距离并输出路径) 堆优化版本 二.最小生成树之 k r u s k a l kruskal k r u s k a l 算法 k r u s k a l kruskal k r u s k a l 完整代码(计算最短距离并输出路径) 三. p r i m prim p r i m 和 k r u s k a l kruskal k r u s k a l 相对比 1. 1. 1 . 时间上 2. 2. 2 . 空间上 3. 3. 3 . USACO07DEC道路建设 B u i l d i n g R o a d s Building Roads B u i l d i n g R o a d s ( p r i m prim p r i m 算法+堆优化与 K r u s k a l Kruskal K r u s k a l +路径压缩对比) 一.最小生成树之 p r i m prim p r i m 算法 Prim算法适用于稠密图 Kruskal适用于稀疏图 M S T MST M S T ( M i n i m u m S p a n n i n g T r e e Minimum Spanning Tree M i n i m u m S p

图论算法-最小生成树

和自甴很熟 提交于 2020-02-14 00:28:29
图论算法-最小生成树 在一个无向图中找出一颗 最小生成树(minimum spanning tree) ,这个问题对有向图也是有意义的,不过找起来更困难。最小生成树存在当且仅当图 G G G 是连通的。在最小生成树中边的条数为 ∣ V ∣ − 1 \left | V \right |-1 ∣ V ∣ − 1 。 Prim算法 在每一步,都要把一个节点当作根并往上边加。在算法的任一时刻,我们都可以看到一个已经添加到树上的顶点集,而其余顶点尚未加到这棵树中,此时,算法在每一阶段都可以通过选择边 ( u , v ) (u,v) ( u , v ) ,使得 ( u , v ) (u,v) ( u , v ) 的值是所有 u u u 在树上但 v v v 不在树上的边值中的最小者,而找出一个新的顶点并把它添加到这棵树中。 代码 这里使用的邻接矩阵。 void Prim ( Graph g ) { VertexType adjver [ VERNUM ] ; WeightType lowcost [ VERNUM ] ; int i , j , k ; WeightType min ; // 初始化,一开始生产树中只有开始的顶点 // 这里开始的顶点的编号为 0 for ( i = 0 ; i < g -> vernum ; i ++ ) { lowcost [ i ] = g -> arc

图论-spfa算法判断负环

大兔子大兔子 提交于 2020-02-12 00:27:00
原理 若存在负环,则迭代玩所有点后边数>=图中点的个数,根据抽屉原理,若edge>=point->图中应当有point+1个点,与point个点矛盾,所以存在负环. 例题 给定一个n个点m条边的有向图,图中可能存在重边和自环, 边权可能为负数。 请你判断图中是否存在负权回路。 输入格式 第一行包含整数n和m。 接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。 输出格式 如果图中存在负权回路,则输出“Yes”,否则输出“No”。 数据范围 1≤n≤2000, 1≤m≤10000, 图中涉及边长绝对值均不超过10000。 输入样例: 3 3 1 2 -1 2 3 4 3 1 -4 输出样例: Yes # include <cstring> # include <iostream> # include <algorithm> # include <queue> using namespace std ; const int N = 2010 , M = 10010 ; int n , m ; int h [ N ] , w [ M ] , e [ M ] , ne [ M ] , idx ; int dist [ N ] , cnt [ N ] ; bool st [ N ] ; void add ( int a , int b , int c ) {

图论-最短路dijsktra算法1

|▌冷眼眸甩不掉的悲伤 提交于 2020-02-07 02:00:31
最短路算法值dijkstra 算法基础思想:贪心 缺点:无法处理负权边。 算法步骤: 1.初始化距离数组dist为0x3f3f3f3f,初始化邻接矩阵为0x3f3f3f3f 2.从第一个定点开始寻找,每次选择与当前未选择的点的集合中距离最短的点。 3.选择该点后更新访问数组st为true 4.更新与该点连接的点的距离。 重复上述操作直到将所有点访问完毕。 例题: 给定一个n个点m条边的有向图,图中可能存在重边和自环,所有边权均为正值。 请你求出1号点到n号点的最短距离,如果无法从1号点走到n号点,则输出-1。 输入格式 第一行包含整数n和m。 接下来m行每行包含三个整数x,y,z,表示存在一条从点x到点y的有向边,边长为z。 输出格式 输出一个整数,表示1号点到n号点的最短距离。 如果路径不存在,则输出-1。 数据范围 1≤n≤500, 1≤m≤105, 图中涉及边长均不超过10000。 输入样例 : 3 3 1 2 2 2 3 1 1 3 4 输出样例: 3 # include <bits/stdc++.h> using namespace std ; const int N = 510 ; int n , m ; int g [ N ] [ N ] ; int dist [ N ] ; bool st [ N ] ; int dijkstra ( ) { memset (

第四关——图论:强连通分量

喜夏-厌秋 提交于 2020-01-21 23:18:40
14:27:28 写一首十几岁听的情歌,可惜我没在那个时候遇见你,否则我努力活到百岁以后,就刚好爱你一整个世纪 ——《 零几年听的情歌 》 今天是待在学校的最后一天了,撒花,庆祝!!! 那也祝自己十六岁生日快乐 最近肺炎传染有点严重,大家能点外卖点外卖,能躺床躺床,少出门,你肆无忌惮赖在家的机会来了!!! 好了,今天要讲的呢,是要待在家好好学习一下的 强连通分量 。 概念 连通分量:在无向图中,即为连通子图。 有向图强连通分量:在有向图G中,如果两个顶点vi,vj间(vi>vj)有一条从vi到vj的有向路径,同时还有一条从vj到vi的有向路径,则称两个顶点强连通(strongly connected)。如果有向图G的每两个顶点都强连通,称G是一个强连通图。有向图的极大强连通子图,称为强连通分量(strongly connected components) 极大强连通子图:G是一个极大强连通子图,当且仅当G是一个强连通子图且不存在另一个强连通子图G’,是得G是G'的真子集 下图中,子图{1,2,3,4}为一个强连通分量,因为顶点1,2,3,4两两可达。{5},{6}也分别是两个强连通分量。 用双向遍历取交集的方法求强连通分量,时间复杂度为O(N^2+M)。 Kosaraju算法或Tarjan算法求强连通分量,两者的时间复杂度都是O(N+M)。 Tarjan算法 基于对图深度优先搜索

图论四:最短路径算法

爷,独闯天下 提交于 2020-01-19 15:25:55
一、广度优先搜索 1、思路:距离开始点最近的点首先被赋值,最远的点最后被赋值。 2、适用范围:对于非负数权的无圈图来说(单源最短路径)。 3、算法实现: (1)一个队列记录每个每个节点的编号。 (2)将起始节点入队,将所有节点到起始节点的距离设置为无穷大,起始节点到起始节点的距离为0; (3)取队列的第一个节点,这个节点出队,遍历这个节点相邻的节点,如果这个节点的距离是INF就变为它前一个节点的距离+1,并且入队。 (4)重复(3)操作,直到所有所有队列为空为止,此时dis数组记录了每一个节点到起始节点的最小距离。 4、代码: #include<iostream> #include<cstdio> #include<queue> #include<vector> using namespace std; const int maxn = 1200; const int INF = 0x3fff; vector <int> vc[maxn]; int dis[maxn]; void bfs(int n) { int i,j,tmp; for(i=1;i<=n;i++) dis[i]=INF; dis[1]=0; queue <int> q; q.push(1); while(!q.empty()) { tmp=q.front(); q.pop(); for(i=0;i<vc[tmp]

图论——遍历算法

烂漫一生 提交于 2020-01-18 14:15:37
文章目录 图论——遍历算法 DFS遍历 BFS遍历 建图类 图论——遍历算法 DFS遍历 深度优先搜索,以深度优先,直到走不下去,回退,对应的数据结构stack 对于上图dfs的流程如下 第一个节点0入栈,把0标记为已访问 遍历0的所有邻接顶点,如果没有被访问就入栈,1入栈,1已访问 遍历1的所有邻接顶点,如果没有被访问就入栈,3入栈,3已访问 遍历3的所有邻接顶点,如果没有被访问就入栈,2入栈,2已访问 遍历2的所有邻接顶点,如果没有被访问就入栈,此时2的邻接顶点全部被访问,2出栈 以此类推3出栈,1出栈,0出栈,遍历完成 代码如下 public class UndirectedGraphDFS { private List < Integer > preOrders = new ArrayList < > ( ) ; private List < Integer > postOrders = new ArrayList < > ( ) ; private UndirectedGraph graph ; private boolean [ ] visited ; public UndirectedGraphDFS ( UndirectedGraph graph ) { this . graph = graph ; visited = new boolean [ graph .

【算法总结】图论-拓扑排序

∥☆過路亽.° 提交于 2020-01-16 13:29:55
【算法总结】图论-拓扑排序 一、概念 设有一个有向无环图(DAG 图),对其进行拓扑排序即求其中结点的一个拓扑序列,对于所有的有向边(U,V)(由U指向V),在该序列中结点U都排列在结点 V 之前。满足该要求的结点序列,被称为 满足拓扑次序的序列 。求这个序列的过程,被称为 拓扑排序 。 由满足拓扑次序序列的特征我们也能得出其如下特点:若结点U经过若干条有向边后能够到达结点V,则在求得的序列中U必排在V之前。 在了解了拓扑次序的定义以后,我们就知道了前文中为什么将拓扑排序限定在一个有向无环图上。若图无向,则边的两个顶点等价,不存在先后关系;若图为有向图,但存在一个环路,则该环中所有结点无法判定先后关系(任意结点间都能通过若干条有向边到达)。 二、拓扑排序的方法 首先,所有有入度(即以该结点为弧头的弧的个数)的结点均不可能排在第一个。那么,我们选择一个 入度为0的结点 ,作为序列的 第一个结点 。当该结点被选为序列的第一个顶点后,我们将该点从图中删去,同时删去以该结点为弧尾的所有边,得到一个新图。那么这个新图的拓扑序列即为原图的拓扑序列中除去第一个结点后剩余的序列。 同样的,我们 在新图上选择一个入度为0的结点 ,将其作为原图的第二个结点,并在新图中删去该点以及以该点为弧尾的边。这样我们又得到了一张新图,重复同样的方法,直到所有的结点和边都从原图中删去。

CCPC-Wannafly-day3

生来就可爱ヽ(ⅴ<●) 提交于 2020-01-14 23:38:27
今天是CCPC训练营的第三天,今天讲的是图论,首先讲了下图的基本术语,发现有好几个以前都没听过(知识点太浅薄了)。然后讲了最小生成树,但老师讲的最小最小生成树不是死模板,进行了一些操作使时间复杂度更小了。然后还讲了拓扑排序,匹配和强连通,这些还好,可以跟上。然后就是带负边的图了,还讲了好多都没听过的一些算法,然后就是一脸懵逼的听着,感觉那个算法很牛逼,但听不怎么懂的那种。 emmmmm,下午又是长达五个小时的比赛。题目难度感觉比区域赛还难(菜是原罪),刷出了两个题就刷不动了,图论题一点思路都没有,其他题好像更难,然后剩下的四个小时都在煎熬都度过。从上午的一些听不懂,到看到下午测试的题,感觉又要自闭了。ε=(´ο`*)))唉,已经连续三次比赛是两个题了………目标:后天一定要刷三个(hhhhhh)。 知道的知识点太少了,晚上讲题时,发现那些题用的算法很多都没学过。 来源: https://www.cnblogs.com/zcb123456789/p/12194316.html