图论

数学之美笔记(六)

淺唱寂寞╮ 提交于 2020-12-13 10:54:47
欧拉七桥问题是图论的开始。 如果一个图能够从一个顶点出发,每条边不重复的遍历一遍回到这个定点,那么顶点度必须为偶数。 广度优先搜素(Breadth-First Search):尽可能“广”的访问每个节点直接连接的其他节点。 深度优先搜索(Depth-First Search):一条路走到黑。 网络爬虫(Web Crawlers)是通过超链接,从任意一个网页出发,用图的遍历算法,自动的访问到每一个网页并把它们存起来的程序。 第一个网络爬虫——网络漫游者是由麻省理工学院的马休 · 格雷写成。 如何构建一个网络爬虫? 用BFS还是DFS?网页爬虫对网页遍历从次序有一个相对复杂的下载优先级排序的子系统即调度系统。当然在调度系统里要存储那些已经发现但是尚未下载的网页的URL,他们一般存在一个优先级队列,而用这种方式遍历互联网,在工程上和BFS更相似。但也不是不用DFS,对于某个网站一般是由特定的一台或者几台服务器专门下载。这些服务器下载完一个网站,然后再进入下一个网站,而不是每个网站轮流下载5%,然后回过头来下载第二批。 页面的分析和URL的提取。 记录哪些网页已经下载过的小本本——URL表。 采用哈希表的好处是判断一个网页的URL是否在表中,平均只需要一次的查找。如果遇到没有下载的网页,除了下载该网页,还需要在下载完成后,将这个网页的URL存到哈希表中。 而多个服务器维护一张哈希表

NOIp 2018 前的图论板子总结

∥☆過路亽.° 提交于 2020-04-07 07:25:05
存图 存边 直接开一个结构体数组存边 struct Edge { int begin, end, weight; } edge[10010]; int edge_count; inline void AddEdge(const int &u, const int &v, const int &w) { edge[edge_count++] = Edge {u, v, w}; } 应用: Kruskal's algorithm Adjacency matrix 用二维数组 adj[i][j] 表示 \(i\) 与 \(j\) 的关系 int adj[1010][1010]; #define ADD_EDGE(u, v, w) adj[u][v] = w 应用: Floyd-Warshall algorithm Hangarian algorithm Kuhn-Munkres algorithm Adjacency list 有几种形式, 以 adj[i] 表示以 \(i\) 为开头的边 应用: 各种图论算法 vector 优点: 访问方便, 存图方便 缺点: 消耗空间, 容易 \(MLE\) ; 删边速度慢 struct Edge { int destination, weight; }; std::vector<Edge> adj[1010]; 加边 #define ADD

图论之最短路径(1)——Floyd Warshall & Dijkstra算法

六月ゝ 毕业季﹏ 提交于 2020-03-27 09:06:43
开始图论学习的第二部分:最短路径。 由于知识储备还不充足,暂时不使用邻接表的方法来计算。 最短路径主要分为两部分:多源最短路径和单源最短路径问题 多源最短路径: 介绍最简单的Floyd Warshall算法: 思路如下:把所有从顶点i到j可能经过的顶点一一枚举,不断更新从i到j的最小权值:d[i][j] = min{d[i][j],d[i][k]+d[k][j]},是一种动规的思想 局限性:不能处理有负权回路(负圈)的情况,而且一般是使用邻接矩阵的方式来实现。 优劣性:思路简单,核心代码简洁易懂,但是时间复杂度为O(N^3)效率较差,适合处理小范围数据。 核心代码只有5行: for (int k = 1; k <= n; k++) for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) if (e[i][j]>e[i][k] + e[k][j]) e[i][j] = [i][k] + e[k][j]; 在情况不是特别复杂的情况下也可以用来求解单源最短路径问题 单源最短路径: 先介绍简单的Dijkstra算法 核心思路:假设计算从顶点1到其余各顶点的最短路径。先用一个一维数组dis储存1号顶点到其余各顶点的初始路程(这时每个值被称为估计值),找到一个离1的距离最小的顶点,比如2,那么dis[2]的值就成为确定值

图论:点分治

做~自己de王妃 提交于 2020-03-20 20:08:53
点分治我感觉是图论树部分比较考验脑力的一种题目了 POJ1741 题意:给一棵边带权树,问两点之间的距离小于等于K的点对有多少个 满足条件的点对有两种情况:两个点的路径横跨树根,两个点位于同一颗子树中 对于根节点进行一次dfs,求出deep,并将其从小到大排序 void getdeep(int x,int fa) { dep[++dep[0]]=d[x]; for(int tmp=g[x];tmp;tmp=e[tmp].next) { if(e[tmp].t==fa||vis[e[tmp].t]) continue; d[e[tmp].t]=d[x]+e[tmp].v; getdeep(e[tmp].t,x); } } 然后看一下calculate int cal(int x,int tmp) { d[x]=tmp;dep[0]=0; getdeep(x,0); sort(dep+1,dep+dep[0]+1); int t=0,l,r; for(l=1,r=dep[0];l<r;) { if(dep[l]+dep[r]<=k) {t+=r-l;l++;} else r--; } return t; } 如果我们已经知道了此时所有点到根的距离a[i] a[x] + a[y] <= k的(x, y)对数就是结果,这个可以通过排序之后O(n)的复杂度求出 然后根据分治的思想

图论笔记

不羁的心 提交于 2020-03-19 00:15:21
目录 最小生成树 例题 怎么证明合数都可以分成素数的乘积 在最大生成树上求两点路径中边权的最小值 kruskal重构树 最短路 SPFA判负环 建图技巧 拓扑排序 queue优化 tarjian 差分约束 环套树/基环树 基环树找环 欧拉图 圈套圈算法 图论 最小生成树 \(N\) 个城市, \(M\) 条可修的公路,每条公路有一个修的成本 \(w_i\) ,要使 \(N\) 个城市连通,所需要的最低成本? 最少需要 \(N-1\) 条边,构成一棵树。 ## Kruskal算法证明 对图的顶点数 \(n\) 做归纳,证明 \(Kruskal\) 算法对任意 \(n\) 阶图都适用 归纳基础 \(n=1\) ,显然能找到最小生成树 归纳过程 例题 P1550 [USACO08OCT]打井Watering Hole 思路就是建立一个超级源点往每个点建一条边权为 \(w_i\) 的边,然后跑最小生成树 怎么证明合数都可以分成素数的乘积 就不写了,我太菜了 在最大生成树上求两点路径中边权的最小值 int f[N][20]; //i的第2^j祖先 int mn[N][20]; //i往上跳2^j祖先所经过的边的最小值 int query(int u,int v) { int ans=inf; if(dep[u]>dep[v]) swap(u,v); for(int i=0,k=dep[v]

Chapter6双指针,BFS和图论

风流意气都作罢 提交于 2020-03-14 15:20:30
Chapter6 双指针,BFS和图论 双指针 1.日志统计 1238 经典的双指针模板题 所谓双指针其实就是针对多重循环的一种优化方式,缩小时间复杂度以确保不会TLE 循环的是一个时间段 #include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #define x first #define y second using namespace std; typedef pair<int, int> PII; const int N = 1e5 + 10; int n, d, k; bool st[N]; int cnt[N]; PII rec[N]; int main() { cin >> n >> d >> k; for(int i = 0; i < n; i++ ) scanf("%d%d", &rec[i].x, &rec[i].y); sort(rec, rec + n); for(int i = 0, j = 0; i < n; i++ ) { int id = rec[i].y; cnt[id]++; while(rec[i].x - rec[j].x >= d) cnt[rec[j].y]--, j++;//优化循环 if(cnt[id] >= k) st[id] =

2019_GDUT_新生专题 图论 k-畅通工程再续

社会主义新天地 提交于 2020-03-12 12:14:38
来源 HDU1875 题目: 相信大家都听说一个“百岛湖”的地方吧,百岛湖的居民生活在不同的小岛中,当他们想去其他的小岛时都要通过划小船来实现。现在政府决定大力发展百岛湖,发展首先要解决的问题当然是交通问题,政府决定实现百岛湖的全畅通!经过考察小组RPRush对百岛湖的情况充分了解后,决定在符合条件的小岛间建上桥,所谓符合条件,就是2个小岛之间的距离不能小于10米,也不能大于1000米。当然,为了节省资金,只要求实现任意2个小岛之间有路通即可。其中桥的价格为 100元/米。 Input 输入包括多组数据。输入首先包括一个整数T(T <= 200),代表有T组数据。 每组数据首先是一个整数C(C <= 100),代表小岛的个数,接下来是C组坐标,代表每个小岛的坐标,这些坐标都是 0 <= x, y <= 1000的整数。 Output 每组输入数据输出一行,代表建桥的最小花费,结果保留一位小数。如果无法实现工程以达到全部畅通,输出”oh!”. Sample Input 2 2 10 10 20 20 3 1 1 2 2 1000 1000 Sample Output 1414.2 oh! 思路:还是kruskal。。。只不过这次要自己建边,小岛个数不超过100,不会超时。 代码: # include <iostream> # include <cstdio> # include

图论学习笔记——最短路

我只是一个虾纸丫 提交于 2020-03-08 09:44:33
背景 最短路问题是重要的最优化问题之一,也是图论研究中的一个经典算法问题,它不仅直接应用于解决生产实践中的众多问题,如管道的铺设、线路的安排、厂区的选址和布局、设备等,而且也经常被作为一种基本工具,用于解决其他的最优化问题以及预测和决策问题。 赋权图 定义:对简单图G的没一边e赋予一个实数,记为 (e),称为边e的 权 ,二没变均赋予权的图称为 赋权图 。 最短路 定义:( , )—路的边权之和称为该路的长,而 , 间路长达到最小的路称顶点u和v的最短路。其 长度称为 和 的距离 ,记为 (x,y)。 最短路问题一般归为两类: (1)求从某个顶点(源点)到其他顶点(终点)的最短路径 (2)求图中每一对顶点间的最短路径。 关于最短路径的研究,目前有很多算法,但基本上是以Dijkstra和Floyd两种算法为基础的,因此这两种算法进行本质的研究非常重要。 设n阶无项或有向联通赋权图gG = (V,E),顶点集V= { , ,····· },边集E= { , ,···· },并且边或弧 上的权值为 ( ),其中 , =1,2,···, 。 显然,对于无向图来说,对任意 , =1,2,···, ,有 = ,故该图的权值矩阵W为对称矩阵。 首先,输入该赋权图的权值矩阵W= ,然后,为了求出两点的最短距离,可按照,只要反复使用,迭代公式 就可以得到最终结果,记为 其中 为从顶点 到顶点

图论题笔记(二):城市地图

穿精又带淫゛_ 提交于 2020-03-03 15:18:57
求从1到5的最短路径,当前用深度搜索解(强化练习深度搜索练习),效率并不高,因为需要遍历所有情况 备注: 1,深广度遍历图都会得到一棵生成树 2,稀疏图并不适合用邻接表,更适合用链表,此处数据较小可以练习邻接表 import copy data='''4 x 0 1 2 0 4 10 1 2 3 1 4 7 2 0 4 2 3 4 3 4 5 4 2 3''' graph_init_row=data.split("\n") end=int(graph_init_row[0].split(" ")[0]) #初始化邻接表 adj_list=[[0]*5 for i in range(5)] for row in graph_init_row[1:]: row_init=list(map(int,row.split(" "))) adj_list[row_init[0]][row_init[1]]=row_init[2] def dfs(cX,adj,path,value,end,minx): #优化 if sum(value)>minx: return if cX==end: global paths,values paths.append(copy.copy(path)) values.append(copy.copy(value)) thev=sum(value) print(

图论学习笔记——顶点的度

梦想的初衷 提交于 2020-03-01 07:35:12
哥尼斯堡七桥问题: 是否能从任意一个顶点开始,通过每条边恰好一次再回到起点? (判断与一个端点 关联的边的数目是否为偶数) 即这个问题的讨论与这个图中的顶点位置无关,我们主要关注的是这个图中的一个点与哪几个点相邻,有几个点与之相邻. 顶点的度 从七桥问题中可以看到,问题是否有解与顶点关联的边的数目的奇偶性有关系。同时对于一个图,我们主要关注的是一个顶点与那几个顶点相邻,因此我们探讨的第一个问题:顶点的度。 定义: 例题: 度序列 邻域 正则图 若一个图中每个点的度都是一个固定整数 k ,则称该图为k -正则图。 度和公式(握手定理) 从顶点度的定义可见,由于每条边有两个端点,从而每条边对一个图的顶点度数总和的贡献为2。因而有: 对每一个图G,均有 这个定理我们也把它形象地称为握手定理。 注:  由握手定理,我们有对一个 k 正则图 G , 若G是k正则图且k是奇数,则p(G)比为偶数。 推论1: 在任何图G=(V,E)中,奇点的个数是偶数。 证明:吧图的顶点按照奇点与偶点分成两个集合V1和V2, 推论2: 图序列 简单图的度序列称为图序列。 例题: 平面上 n个点,任意两个点之间的距离至少是1。证明:在这n个点中,距离为1的点对的数目不超过 3n 。 解: 证: 首先构图G= (V,E),其中V表示平面上的顶点。V中两个点有边连接当且仅当这两个点之间的距离恰好为1,则图G是简单图