图论

[转]图论题集

假如想象 提交于 2020-02-29 20:23:55
========以下是最小生成树+并查集========== HDU 1213 基础并查集★ HDU 1272 基础并查集★ HDU 1325 Tree? HDU 1856 基础并查集★ HDU 1102 基础最小生成树★ HDU 1232 基础并查集★ HDU 1233 基础最小生成树★ HDU 1863 基础最小生成树★ HDU 1875 基础最小生成树★ HDU 1879 基础最小生成树★ HDU 3371 简单最小生成树★ HDU 1301 基础最小生成树★ HDU 1162 基础最小生成树★ HDU 1198 基础最小生成树★ HDU 1598 HDU 1811 并查集+拓扑排序★★ HDU 3926 同构图★ HDU 3938 离线+并查集★★ HDU 2489 dfs枚举组合情况+最小生成树★ HDU 4081 National HDU 4126 Conqueror HDU 1829 基础种类并查集★ HDU 1558 计算几何+并查集★ HDU 3461 并查集(有点难想到)★★ HDU 3367 最大生成树★ HDU 2473 并查集+设立虚父节点(马甲)★★ HDU 3172 带权并查集★ HDU 3635 带权并查集★ HDU 3047 带权并查集★ HDU 3038 HDU 2818 带权并查集★ HDU 3234 异或并查集(难)★★★ HDU 2121

图论整理

假如想象 提交于 2020-02-28 04:59:20
图的基本概念 根据之前博客 数据结构整理 中,我们可以知道 是一种线性数据结构 是一种树结构 而这样一种结构就是一种图的结构 图的每一个点称为 顶点(Vertex) ,通常我们会给顶点标上序号,而这些序号就可以理解为 索引 当然这是一种抽象后的概念,在实际中,图可以表示为很多,比如社交网络 顶点与顶点相连的称为 边(Edge) 而由以上的图中,由于各个顶点相邻的边是没有方向的,所以这种图又被称为 无向图(Undirected Graph) , 在无向图中,只要两个顶点相连,那么无论从哪个顶点出发都可以到达相邻的顶点 。而类似于下图的图是有方向的 我们称之为 有向图(Directed Graph),在有向图中,只能够从起始顶点出发到达方向末端的相邻顶点,相反则不可以。 所以我们在考虑现实关系建模的时候,要使用无向图还是有向图,比如地铁站点之间,无论从哪个站点出发都可以到达相邻的同一个线路的站点,所以要使用无向图。在社交网络中,如果是微信中,可以使用无向图,因为微信中人与人的关系是好友的关系。但有一些社交工具可能是一种关注的关系,而不是好友的关系。比如像下图中,Anne关注了Bob,而Bob并没有关注Anne,这样我们就必须使用有向图来进行建模。 如果一个图中,顶点与顶点的边只代表一种关系,而没有任何实际的度量,我们可以称这种图为 无权图 。而在有一些图中

图论——最短路径问题

廉价感情. 提交于 2020-02-27 15:57:41
之前自己看过和总结过相关的东西,今天再总结说一下; 感觉权值问题,是否无向有向,权值正负可以直接用不同的算法进行解决; 这次还是主要说一说四种算法:迪杰斯特拉算法、BF算法、SPFA算法、弗洛伊德算法; 迪杰斯特拉算法: 老生常谈最简单的一种算法,从某一点出发,建立Distance数组,不断地寻找当前最近节点,并且选择该节点后,以该节点作为中介,更行其他的全不distance长度; 个人认为适合单源到多点的路径问题; 之前做的总结 https://blog.csdn.net/InNoVaion_yu/article/details/86629313 但是仍然需要注意的是该算法的衍生问题:多路径问题; 对于多路径问题往往加限定条件; 不加任何条件的整体代码: #include<stdlib.h> #include<stdio.h> #include<algorithm> #include<string> #include<iostream> #include<vector> using namespace std; using std::vector; const int MAXV=1000; const int INF=1000000000; struct Node{ int v,dis; }; vector<Node>Adj[MAXV];//图的存储 int d[MAXV];/

算法——图的深度优先遍历和广度优先遍历

你。 提交于 2020-02-27 14:26:45
更多参考: 深度优先遍历:深度优先遍历是图论中的经典算法。其利用了深度优先搜索算法可以产生目标图的相应拓扑排序表,采用拓扑排序表可以解决很多相关的图论问题,如最大路径问题等等。 根据深度优先遍历的特点我们利用Java集合类的栈Stack先进后出的特点来实现。我用二叉树来进行深度优先搜索。 深度优先搜索的步骤为: (1)首先节点 1 进栈,节点1在栈顶; (2)然后节点1出栈,访问节点1,节点1的孩子节点3进栈,节点2进栈; (3)节点2在栈顶,然后节点2出栈,访问节点2 (4)节点2的孩子节点5进栈,节点4进栈 (5)节点4在栈顶,节点4出栈,访问节点4, (6)节点4左右孩子为空,然后节点5在栈顶,节点5出栈,访问节点5; (7)节点5左右孩子为空,然后节点3在站顶,节点3出栈,访问节点3; (8)节点3的孩子节点7进栈,节点6进栈 (9)节点6在栈顶,节点6出栈,访问节点6; (10)节点6的孩子为空,这个时候节点7在栈顶,节点7出栈,访问节点7 (11)节点7的左右孩子为空,此时栈为空,遍历结束。 广度优先遍历:广度优先遍历是连通图的一种遍历策略,因为它的思想是从一个顶点V0开始,辐射状地优先遍历其周围较广的区域故得名。 根据广度优先遍历的特点我们利用Java数据结构队列Queue来实现。 广度优先搜索的步骤为: (1)节点1进队,节点1出队,访问节点1 (2

图论之链式前向星

主宰稳场 提交于 2020-02-26 10:35:00
前向星是一种特殊的边集数组,相比较于邻接矩阵,大大地节省了存储空间。前向星可以说是近乎完美的。 如下图所示: 输入顺序为: 1 2 1 3 1 4 2 4 我们现在将会用链式前向星存储这个图。 首先建立一个结构体: struct EDGE { int pre; int dis; int to; }edge[11]; int edge_sum,head[5]; pre代表与第i条边同起点的上一条边的存储位置。当该边为当前顶点的第一条边时,pre=0。 dis代表该边的权值,可以理解为长度。 to代表该边指向的顶点。 edge_sum代表边的总数,head代表该顶点的最后一条出边。 接下来是加边的函数。 void add_edge(int from,int to,int dis) { edge_sum++; edge[edge_sum].pre=head[from]; edge[edge_sum].dis=dis; edge[edge_sum].to=to; head[from]=edge_sum; } 模拟一遍。 edge[1].pre=0  edge[1].dis=1  edge[1].to=2  head[1]=1  (1->2) edge[2].pre=0  edge[2].dis=1  edge[2].to=1  head[2]=2  (2->1) edge[3].pre=1

【读书笔记】《王道论坛计算机考研机试指南》 第四、五章

一曲冷凌霜 提交于 2020-02-26 00:36:02
目录 第四章 数学问题 %运算符 第五章 图论 第四章 数学问题 %运算符 1. a%b 中a、b必须为整型变量,不能为浮点数;b变量必须为非0值,否则程序异常终止; 2. 若a为正数,则表达式结果为非负数;若a为负数,则表达式结果为非正数;与b的符号无直接关系, a%(-b)==a%b 3. 避免大数求模中的溢出问题,运用以下规律: (a*b)%c=(a%c*b%c)%c; (a+b)%c=(a%c+b%c)%c; 第五章 图论 来源: https://www.cnblogs.com/wwj321/p/12364816.html

图的拓扑排序——卡恩算法

我的梦境 提交于 2020-02-25 10:25:54
拓扑排序 有向图的拓扑排序是其顶点的线性排序,使得对于从顶点u 到顶点v 的每个有向边uv ,u 在排序中都在v 之前。 在图论中,由一个 有向无环图 的顶点组成的序列,当且仅当满足下列条件时,称为该图的一个 拓扑排序 ( Topological sorting)。 每个顶点出现且只出现一次; 若A在序列中排在B的前面,则在图中不存在从B到A的路径 。 //#include<Windows.h> #include<iostream> #include<cstring> #include<cstdio> using namespace std; const int maxn = 105; const int MAX_E = 10005; const int MAX_V = 105; struct ENode { int to; int Next; }; ENode Edegs[MAX_E]; int Head[MAX_V]; int tnt; void Add_ENode(int w, int v) { ++tnt; Edegs[tnt].to = v; Edegs[tnt].Next = Head[w]; Head[w] = tnt; /*可以拓扑排序则保证这是一个有向图*/ } int IN_degree[maxn];//记录每个点的入度; int Queue[maxn];

与图论的邂逅04:LCT

不想你离开。 提交于 2020-02-24 16:23:01
  本着对数据结构这一块东西的一股兴趣,最近在集训的百忙之中抽空出来学LCT,终于学懂了这个高级玩意儿。 前置知识:Splay和树链剖分   Splay挺复杂的......这里就先不写,不然篇幅太大。树链剖分倒是可以大致地讲一下。 树链剖分   什么是树链剖分呢?就是把树给解剖成一条条的链子啦~那就先从最常用的重链剖分讲起。对于当前节点u和它的儿子构成的点集V,若size[v]=max{size[w] | w∈V},也就是以u的儿子为根的所有子树中size最大的那个儿子是v,那么称v是u的重儿子(定义size[x]:以x为根的子树所含有的点数)。如果这时把u向v连一条边,并且其它所有点也像这么做(连向它们的重儿子,叶子节点除外),由于重儿子唯一,父亲唯一,所以就会形成一条一条的链。这个链就叫重链。重链剖分是如此,类比一下就能够理解长链剖分:每个点连向子树深度最大的那个儿子。然而这两种剖法都不是LCT所使用的。LCT使用的是:实链剖分。   实链剖分就是说,把某个节点向它的某个儿子连实边,向其它儿子连虚边,这样也能连出一条条链子。实链剖分有什么好处呢?重链剖分和长链剖分中的size和dep都是固定的,也就是说剖完一棵树之后就无法再改变。而注意刚才实链剖分定义中的一句话:"把某个节点向它的某个儿子连实边",也就是说这个"某个儿子"是可以改变的

【图论】拓扑排序

帅比萌擦擦* 提交于 2020-02-22 17:41:56
板子题:hihocoder-1174 # include <bits/stdc++.h> # define ll long long # define endl '\n' using namespace std ; const int INF = 0x3f3f3f3f ; const int mod = 1e9 + 7 ; const int maxn = 1e5 + 10 ; ll n , m , num ; ll InDeg [ maxn ] ; vector < ll > vec [ maxn ] ; queue < ll > q ; bool topsort ( ) { while ( ! q . empty ( ) ) q . pop ( ) ; //初始化清空队列 num = 0 ; for ( ll i = 1 ; i <= n ; i ++ ) if ( ! InDeg [ i ] ) q . push ( i ) ; //遍历寻找入度为0的点加入队列 while ( ! q . empty ( ) ) { ll now = q . front ( ) ; q . pop ( ) ; num ++ ; //如果该点入度为0,则加入到拓扑序列之中去 for ( ll i = 0 ; i < vec [ now ] . size ( ) ; i ++ ) { if (

图论

大城市里の小女人 提交于 2020-02-21 22:53:31
图论 拓扑排序 最小生成树 最短路 #include <bits/stdc++.h> #include <vector> #include <algorithm> using namespace std; const int MAXN = 1e5+10; int n, m; ////加带权边 //自建结构体 struct Edge { int v; int w; }; Edge make_Edge(int v, int w) { Edge cur; cur.v = v; cur.w = w; return cur; } vector<Edge> G[MAXN]; void addEdge(int u, int v,int w) { G[u].push_back(make_Edge(v, w)); G[v].push_back(make_Edge(u, w)); } //pair vector<pair<int, int>> A[MAXN]; void addedge(int u, int v, int w) { A[u].push_back(make_pair(v, w)); A[v].push_back(make_pair(u, w)); } int main() { system("pause"); return 0; } /**************************