图论

《数学之美》--吴军

孤街醉人 提交于 2019-11-30 14:12:44
前段时间开始看吴军写的一本很经典的书--《数学之美》。 然后下面是我的读书小笔记(回忆一下,看自己看进去多少东西): 关于数学的重新认识: 从小学到大的数学,在我的认知里,数学就是计算,推理+证明。这本书从人类的起源来演绎了数学的由来。让我印象最深的一句就是: 数学:就是通过学习获取知识。 世界万物皆可量化,这就意味着全都脱离不了数学。 图论和网络爬虫 这里讲到 哥尼斯 堡的 七座桥 问题,可以简化成下面的图例: 命题:从从以上图中任意一个节点出发,要求必须经过每一个线段且不能有任意重复经过的地方,并且要求最终回到起点的位置。 证明其是否有可行的方案。 证明: pass 上面研究 哥尼斯 堡的 七座桥问题就是图论。 图论是离散数学的一个分支。 图论中的图是由若干给定的点及连接两点的线所构成的图形,这种图形通常用来描述某些事物之间的某种特定关系,用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。 那么网络爬虫又跟图论有什么关系呢? 网络爬虫就是获取网络中的网页数据,这里我们讲的主要偏向通用爬虫,也就是搜索引擎的爬取模式。我们将网络上的每一个页面看成一个特定的点,网页的url看成点与点之间的连线。于是整个网络上的网页就形成成了图论中的网状结构图。那么爬虫从任意一个节点出发,无论使用BFS还是DFS都能将整个网络的资源获取到,当然不只是BFS和DFS这两种遍历方法那么简单。

与图论的邂逅09:树上启发式合并

陌路散爱 提交于 2019-11-29 20:04:45
启发式树上合并 先看这样一个例题: 给定一个长度为 \(10^5\) 的序列,序列中都是 \([0,1000000]\) 的整数,接下来有 \(10^5\) 次询问,共两种询问:修改序列某个位置的值,以及查询区间 \([L,R]\) 内一共有多少种不同的数。 先不考虑线段树的做法。 我们可以想到用莫队来解这道题———按莫队的套路排序后用桶来维护即可,至多1000000个桶,复杂度 \(O(N\sqrt{N})\) 。可以看到,我们的核心思路就是排序后改变了每个位置的访问顺序,从而降低了复杂度。 然后我们看到下面的例题( 如果上面不是为了引出dsu我会乱说? ): 给定一棵大小为 \(10^6\) 的树,树上每个点都是一个 \([0,1000000]\) 的整数,接下来有 \(10^5\) 次询问,查询某棵子树内一共有多少种不同的数。 树上莫队?不过我现在需要 \(NlogN\) 的算法。那么我们参考一下莫队的思想,可不可以通过修改访问顺序来降低复杂度?这个算法叫“树上启发式合并”,一般写 \(dsu\) 。 考虑暴力的做法,就是暴力处理出所有子树的答案,再 \(O(1)\) 回答。递归遍历整棵树,然后对于每个点 \(u\) ,暴力计算 \(u\) 子树的答案。复杂度为 \(O(N^2)\) 。 在我们计算完 \(u\) 的儿子 \(v\) 的答案后,我们需要计算 \(v\)

图论排序---拓扑排序

青春壹個敷衍的年華 提交于 2019-11-29 19:18:23
定义 对于有向无权无环图,进行拓扑排序 实现方式 Kahn算法 基于DFS的拓扑排序算法 Kahn算法 排序的过程 1.对于DAG,先输出没有前驱的点 2.把与前驱相关的边删除 3.继续输出没有前驱的点 4.重复前者,直到DAG为空或者没有前驱 如果我们有如下的一个有向无环图,我们需要对这个图的顶点进行拓扑排序,过程如下: 首先,我们发现V6和v1是没有前驱的,所以我们就随机选去一个输出,我们先输出V6,删除和V6有关的边,得到如下图结果: 然后,我们继续寻找没有前驱的顶点,发现V1没有前驱,所以输出V1,删除和V1有关的边,得到下图的结果: 然后,我们又发现V4和V3都是没有前驱的,那么我们就随机选取一个顶点输出(具体看你实现的算法和图存储结构),我们输出V4,得到如下图结果: 然后,我们输出没有前驱的顶点V3,得到如下结果: 然后,我们分别输出V5和V2,最后全部顶点输出完成,该图的一个拓扑序列为: v6–>v1—->v4—>v3—>v5—>v2 应用 给出n个点,m个关系 再给出u,v,表示u比v厉害 然后进行排序 邻接矩阵版Kahn算法的拓扑排序 传送门 裸拓扑排序 #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; const int

图论 - PAT甲级 1013 Battle Over Cities C++

纵饮孤独 提交于 2019-11-29 16:41:39
PAT甲级 1013 Battle Over Cities C++ It is vitally important to have all the cities connected by highways in a war. If a city is occupied by the enemy, all the highways from/toward that city are closed. We must know immediately if we need to repair any other highways to keep the rest of the cities connected. Given the map of cities which have all the remaining highways marked, you are supposed to tell the number of highways need to be repaired, quickly.For example, if we have 3 cities and 2 highways connecting city​1​​-city​2​​ and city​1​​-city​3​​. Then if city​1​​ is occupied by the enemy, we

【图论】最短路专题

允我心安 提交于 2019-11-29 16:09:38
入门题: poj 2387(单源最短路径)------- dijkstra模板题o(n^2) 但是需要注意题中是可以存在重边的,所以需要判断cost[i][j]>w时cost[i][j]=w 在这里wa过几次 #include<stdio.h> #include<iostream> #include<string.h> #include<algorithm> using namespace std; const int MAXN=1010; //*************************************************************** //Dijkstra-数组实现O(n^2) //单源最短路径 //lowcost[]---从点beg到其他点的距离 //不记录路径 //结点编号从1开始的 //**************************************************************** #define INF 0x3f3f3f3f //这个无穷大不能太大,防止后面溢出 #define typec int bool vis[MAXN]; void Dijkstra(typec cost[][MAXN],typec lowcost[MAXN],int n,int beg) { typec minc; int i,j

图论——图的表示

非 Y 不嫁゛ 提交于 2019-11-29 15:55:15
一、邻接矩阵 邻接矩阵g[i][j]即表示顶点i到顶点j是否有一条有向边,有为1,无为0。 二、邻接表 第i行的每个数表示顶点i到该顶点有一条有向边。 三、前向星 等价于n个单向链表,简单易懂。 struct edges{ int to; int w; int next; }edge[MAX_N]; int idx; int h[MAX_N]; void add_edge(int u,int v,int w) { edge[++idx].w=w; edge[idx].to=v; edge[idx].next=h[u]; h[u]=idx; } 来源: https://www.cnblogs.com/ninedream/p/11521349.html

图论--第K短路(A*思想)

[亡魂溺海] 提交于 2019-11-29 04:45:38
k短路求解: k短路 = 单源点最短路跑反向边 + 高级搜索A* A*算法 结合了启发式方法和形式化方法; 启发式方法通过充分利用图给出的信息来动态地做出决定而使搜索次数大大 降低; 形式化方法不利用图给出的信息,而仅通过数学的形式分析; 算法思路: 算法通过一个估价函数f(h)来估计图中的当前点p到终点的距离,并由此决定它的搜索方向; 当这条路径失败时,它会尝试其他路径; 对于A*,估价函数=当前值+当前位置到终点的距离,即f(p)=g(p)+h(p),每次扩展估价函数值最小的一个; 对于K短路算法来说,g(p)为当前从s到p所走的路径的长度;h(p)为点p到t的最短路的长度; f(p)的意义为从s按照当前路径走到p后再走到终点t一共至少要走多远; 为了加速计算,h(p)需要在A*搜索之前进行预处理,从终点t做一次单源点最短路径就能得到每个点的h(p)了; 算法步骤: (1) ,以原终点 t 为源点,求解 t 到所有点的最短距离(即: 跑一遍最短路 ); (2) ,新建一个 优先队列 , 将源点s加入到队列中; (3) ,从优先级队列中弹出f(p) 距离最小 的点p,如果点p就是t,则计算t出队的次数; 如果当前为 t的第k次出队 ,则当前路径的长度就是 s到t的第k短路的长度 ,算法结束; 否则遍历与p相连的所有的边,将扩展出的到p的邻接点信息加入到优先级队列; 代码:

集合选数 状压DP+图论

别说谁变了你拦得住时间么 提交于 2019-11-28 23:08:22
集合选数 问题: 《集合论与图论》这门课程有一道作业题,要求同学们求出{ \(1, 2, 3, 4, 5\) }的所有满足以 下条件的子集:若 \(x\) 在该子集中,则 \(2x\) 和 \(3x\) 不能在该子集中。 同学们不喜欢这种具有枚举性 质的题目,于是把它变成了以下问题:对于任意一个正整数 \(n≤100000\) ,如何求出{ \(1, 2,…, n\) } 的满足上述约束条件的子集的个数(只需输出对 \(1,000,000,001\) 取模的结果),现在这个问题就 交给你了。 解: 这是一道图论题 题目暗示 首先我们先考虑构图 将基础位置的2倍放在他的下方 3倍放在右方 你就可以构建一个矩阵 然后你就会惊奇地发现这 要求一个数上下左右不相邻 这不就是玉米地或者是 炮兵阵地 那道题么? 状态转移就不说了吧 然后根据乘法原理 答案为: $ \prod \sum f[las][j]$ $ f[i][j] \(表示 第\) i \(行状态为\) j$的方案数 我不会说我最后一个点被卡我打了一波表 code: // #include<stdio.h> #include<bits/stdc++.h> using namespace std; #define maxnn 100010 #define ll long long #define mod 1000000001 int

图论--DFS总结

随声附和 提交于 2019-11-28 18:51:17
1.Key word: ①双向DFS ②回溯 今天就看到了这么多DFS,其实DFS更倾向于枚举所有情况。 对于双向DFS,我们考虑看看最短路,起点做一下搜索,记录一下到所有点的距离,终点做一下搜索,记录一下到所有点的距离,那么起点到任一点的距离加上终点到任一点的距离那不就是起点到终点经过这一点的最短距离,我觉得BFS也可以实现,所以在我眼里BFS相对于DFS更强一点,只有说得到特定的某一结果的时候深搜可能会好一点。 设计回溯,所谓回溯就是还原现场,保证在执行另一分支的时候能够保证所以的改变只受当前状态的影响,所以在一条路走不通时就要修改,不过通过特殊的修改可以达到特殊的回溯效果,回溯时剪枝,回溯时调整路线,都是可以的。 DFS题型: 哈密尔顿路径 欧拉回路 连通性 枚举题目 全排列(也是枚举)所以DFS对于状态的找寻比较局限,目前还没看到更好的题目。 来源: https://blog.csdn.net/weixin_43627118/article/details/100107848

【图论】【刷题】蓝题

大兔子大兔子 提交于 2019-11-28 18:28:44
1>神经网络 绿题 为什么用拓扑? 1)必备条件:DAG 2)本题的公式上,显示需要计算出能连接到本点的,全部的边值*点值 故而当我开始推这个点时,他的所有先驱点的状态全部都要求完 这只能是topo_sort #include<cstdio> #include<cstdlib> #include<queue> #include<vector> using namespace std; int n,m; const int N=103; int c[N],in[N],sz[N]; struct node { int v,w; node(int vv,int ww) { v=vv,w=ww; } node(){} }; vector <node > g[N]; queue <int > q; void topo_sort() { while(!q.empty()) { int t=q.front();q.pop(); sz[t]=g[t].size() ; for(int i=0;i<sz[t];i++) { node v=g[t][i]; if(c[t]>0) c[v.v ]+=c[t]*v.w ; if(--in[v.v ]==0) q.push(v.v ); } } } int main() { scanf("%d%d",&n,&m); int x; for(int i=1;i<