ACM图论基础算法概论

合集下载

ACM培训——图论(一)

ACM培训——图论(一)
设x[i]等于1或0, 表示边e[i]是否属于生成树. 则比率 r = ∑(benifit[i] * x[i]) / ∑(cost[i] * x[i]), 0≤i<m . 令: z = ∑(benifit[i] * x[i]) - l * ∑(cost[i] * x[i]) 两个性质: 1. z单调递减 证明: 因为cost为正数, 所以z随l的减小而增大. 2. z( max(r) ) = 0 证明: 若z( max(r) ) < 0, ∑(benifit[i] * x[i]) - max(r) * ∑(cost[i] * x[i]) < 0, 可化为 max(r) < max(r). 矛盾; 若z( max(r) ) >= 0, 根据性质1, 当z = 0 时r最大.
Prim算法
• 贪心准则
– 加入后仍形成树,且耗费最小 – 始终保持树的结构——Kruskal算法是森林
• 算法过程
– 从单一顶点的树T开始 – 不断加入耗费最小的边(u, v),使T∪{(u, v)}仍 为树 ——u、v中有一个已经在T中,另一个 不在T中
Prim 算法过程
8 4 a 8 h 1 g 2 f b 2 i 7 6 10 c 7
一、图的BFS遍历
算法步骤: 1、用dis[]数组表示各点距离起点S的距离。dis[i]=-1表示i点还 未被访问。用map[i][j]表示i点和j点之间是否有边。 2、将dis[s]初始化为0,将其它点的dis初始化为-1。将S点入队 3、while(队列非空) { 从队首出队一个元素u { 对于所有跟u有边相连的点v: if(dis[v]==-1) { dis[v]=dis[u]+1; v入队 } } }
int findp (int x) { return p[x]==-1?x:p[x]=findp(p[x]); } bool reunion (int x, int y) { int px=findp(x); int py=findp(y); if(px==py) { return false; } p[px]=py; return true; }

ACM程序设计算法原理和ACM入门

ACM程序设计算法原理和ACM入门

}
2020/5/11
40
伪代码——算法语言
伪代码(Pseudocode):介于自然语言和 程序设计语言之间的方法,它采用某一程序 设计语言的基本语法,操作指令可以结合自 然语言来设计。
优点:表达能力强,抽象性强,容易理解
2020/5/11
41
欧几里德算法
1. r = m % n; 2. 循环直到 r 等于0
2020/5/11
32
【例2】变量计数之一。
(1) x=0;=0;
(2) for(k-1;<=n;++)
(3) x++;
(4) for(i=1;<=n;++)
(5) for(j=1;j<=n;++)
(6) y++;
该算法段的时间复杂度为T(n)=Ο(n2)。
当有若干个循环语句时,算法的时间复杂度是由嵌 套层数最多的循环语句中最内层语句的频度f(n)决定的。
2020/5/11
7
2010年的风采
2020/5/11
8
2020/5/11
9
2020/5/11
10
2020/5/11
11
2020/5/11
12
2020/5/11
13
2020/5/11
14
2020/5/11
15
2020/5/11
16
2020/5/11
17
2020/5/11
18
2020/5/11
19
2020/5/11
20
2020/5/11
21
2020/5/11
22
第一部分 算法概述

ACM程序设计基础之图论

ACM程序设计基础之图论
x=select(C); //在候选集合C中做贪心选择 if feasible(S, x) //判断集合S中加入x后的解是否可行
S=S+{x}; C=C-{x}; } return S; }
9
例1、 活动安排问题
活动安排问题就是要在所给的活动集合中选出 最大的相容活动子集合,是可以用贪心算法有效求解 的很好例子。该问题要求高效地安排一系列争用某一 公共资源的活动。贪心算法提供了一个简单、漂亮的 方法使得尽可能多的活动能兼容地使用公共资源。
24
至少有三种看似合理的贪心策略: (1)选择价值最大的物品,因为这可以尽可能快
地增加背包的总价值。但是,虽然每一步选择获得 了背包价值的极大增长,但背包容量却可能消耗得 太快,使得装入背包的物品个数减少,从而不能保 证目标函数达到最大。
(2)选择重量最轻的物品,因为这可以装入尽可 能多的物品,从而增加背包的总价值。但是,虽然 每一步选择使背包的容量消耗得慢了,但背包的价 值却没能保证迅速增长,从而不能保证目标函数达 到最大。
2.最优子结构性质
当一个问题的最优解包含其子问题的最优解 时,称此问题具有最优子结构性质。问题的最 优子结构性质是该问题可用动态规划算法或贪 心算法求解的关键特征。
19
贪心与动态规划
• 【例】在一个N×M的方格阵中,每一格子赋予一 个数(即为权)。规定每次移动时只能向上或向 右。现试找出一条路径,使其从左下角至右上角 所经过的权之和最大。
i 1 2 3 4 5 6 7 8 9 10 11 S[ 1 3 0 5 3 5 6 8 8 2 12 i] f[i] 4 5 6 7 8 9 10 11 12 13 14
14
例1、 活动安排问题
算法greedySelector 的 计算过程如左图所示。 图中每行相应于算法的 一次迭代。阴影长条表 示的活动是已选入集合A 的活动,而空白长条表 示的活动是当前正在检 查相容性的活动。

图论算法总结及图论建模

图论算法总结及图论建模

else if (v in S)
// 如果节点v还在栈内
Low[u] = min(Low[u], DFN[v])
if (DFN[u] == Low[u])
// 如果节点u是强连通分量的根
repeat
v = S.pop
// 将v退栈,为该强连通分量中一个顶点
print v
until (u== v)
}
算法演示
边的分类
一条边(u, v)可以按如下规则分类
• 树边(Tree Edges, T): v通过边(u, v)发现 • 后向边(Back Edges, B): u是v的后代 • 前向边(Forward Edges, F): v是u的后代 • 交叉边(Cross Edges, C): 其他边,可以连接同一个DFS树中没
1. 2. procedure tarjan(u:longint); var p:node; v:longint; begin f[u]:=false;inc(top);stack[top]:=u; instack[u]:=true;p:=head[u]; inc(time);dfn[u]:=time;low[u]:=time; while p^.key<>u do begin v:=p^.key; if f[v] then begin tarjan(v); low[u]:=min(low[u],low[v]);
tarjan(j); if (LOW[j]<LOW[i])
LOW[i]=LOW[j]; } else if (instack[j] && DFN[j]<LOW[i])
LOW[i]=DFN[j]; }
if (DFN[i]==LOW[i]){ Bcnt++; do { j=Stap[Stop--]; instack[j]=false; Belong[j]=Bcnt; } while (j!=i);

ACM算法总结

ACM算法总结
七.计算几何学.
(1)几何公式.
(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等). (poj2031,poj1039)
(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)
(poj1408,poj1584)
(4)最小树形图(poj3164)
(5)次小生成树.
(6)无向图、有向图的最小环
三.数据结构.
(1)trie图的建立和应用. (poj2778)
(2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和 在线算法
(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)
(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)
五.动态规划
(1)背包问题. (poj1837,poj1276)
(2)型如下表的简单DP(可参考lrj的书 page149):
(4)凸包. (poj2187,poj1113)
中级:
一.基本算法:
(1)C++的标准模版库的应用. (poj3096,poj3007)
(2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)
二.图算法:
(3)记忆化搜索(poj3373,poj1691)
五.动态规划
(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)
(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)
(2)四边形不等式理论.

ACM基础——图

ACM基础——图

Status CreateMG(MGraph &G){ //无向图的构造 int i,j,k,v1,v2; scanf("%d%d",&G.vexnum,&G.arcnum); for(i=0;i<G.vexnum;i++) scanf(“%d”,&G.vexs[i]); //输入顶点数据 for(i=0;i<G.vexnum;i++) for(j=0;j<G.vexnum;j++) G.arcs[i][j].adj = 0; //初始化结束 for(k=0;k<G.arcnum;k++){ scanf("%d%d",&v1,&v2); i=LocateVex(G,v1); j=LocateVex(G,v2); G.arcs[i][j].adj=1; G.arcs[j][i].adj=G.arcs[i][j].adj; //创建有向图屏蔽此句 } return OK; }
0 0 0
1
1 0 0
Байду номын сангаас
3
2 1 2
V2
V4
V3 V4
图的邻接矩阵表示
# define INFINITY INT_MAX //表示不可达 # define MAX_VERTEX_NUM 20 //最大顶点个数
typedef int VRType;
//顶点关系类型
typedef int VertexType; //顶点数据类型

• 图的基本概念 • 图的存储 • 图的遍历
图(Graph)是由有穷非空的顶点集合和一个描述 顶点之间关系的边(或者弧)的集合组成。

acm算法浅谈图论模型的建立与应用

acm算法浅谈图论模型的建立与应用

1 2
3 4
例题1 Place the Robots(ZOJ)
小结
比较前面的两个模型:模型一过于简单,没有给问 题的求解带来任何便利;模型二则充分抓住了问题的内 在联系,巧妙地建立了二部图模型。为什么会产生这种 截然不同的结果呢?其一是由于对问题分析的角度不同: 模型一以空地为点,模型二以空地为边;其二是由于对 原型中要素的选取有差异:模型一对要素的选取不充分, 模型二则保留了原型中“棋盘”这个重要的性质。由此 可见,对要素的选取,是图论建模中至关重要的一步。
构图
S
例题3 贪婪之岛(ZOJ)
1 P1
2
P2
3
T
4 P3
5
每张卡片i用顶点i表示,另外加三个顶点P1,P2,P3,表 示三种能力,还有源点S,汇点T。
构图
S
例题3 贪婪之岛(ZOJ)
P1
B,0
P2
P3
1
2
3
T
4
5
从源点分别向P1,P2,P3引一条弧,容量分别为A,B,C, 费用为0。
构图
S
例题3 贪婪之岛(ZOJ)
下面我们来轻松一下,欣赏一下几个经 典的广告词
优秀广告词:早点下斑 不再逗留 默默无蚊 衣衣不舍 百衣百顺 鸡不可失
那么请问你们对于这种改动成语的广告有什 么看法呢?
我还搜集了一些很经典的广告
借问酒家何处有,牧童遥指杏花村。 (山西杏花村酒) 三十功名创传奇,八千里路驰江铃。 (江铃摩托) 禁止抽烟,连皇冠牌也不例外。 车到山前必有路,有路必有丰田车。 (丰田车)
第三块内容: 下面说的一定是大家感兴趣的东西
这是一段网络语言:周末,读大学的GG(哥 哥)回来,给我带了很多好东西,都系 ‘偶’(我)非常‘稀饭’(喜欢)的。就‘酱 紫’(这样子),‘偶’(我)就答应GG陪他去 逛街吃KPM(肯德基、比萨饼、麦当劳)。

图论基本算法

图论基本算法

图论基本算法图论是NOIP必考的知识点。

松弛操作如图:⽐如说从1到2可以有2种解法,⼀种是直接⾛,另⼀种就是⽤⼀个点来中转;从这两条路上选最短的⾛法的操作就叫松弛。

根据这个操作啊就可以做出像暴⼒⼀样的最短路算法————Floyd算法.我们可以先初始化把不相连的边都设为⽆穷⼤,再不断进⾏松弛操作不断更新最短路。

这样就可以得出所有的两点之间的最短路,还能处理负边权。

不过就是有点慢时间复杂度是O(n3)for(k=1;k<=n;k++) //中转点for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(dis[i][j]>dis[i][k]+dis[k][j]) //松弛操作dis[i][j]=dis[i][k]+dis[k][j];但是该算法适⽤于求解多源最短路径,所以时间复杂度⼤也是正常的。

⽽单源最短路径主要有两种Dijkstra算法O(n2)加堆优化O(nlogn)⽤来计算从⼀个点到其他所有点的最短路径的算法。

Dijkstra它不能处理存在负边权的情况。

算法描述:设起点为s,dis[v]表⽰从s到v的最短路径,。

a)初始化:dis[v]=∞(v≠s); dis[s]=0;;b)For (i = 1; i <= n ; i++)1.在没有被访问过的点中找⼀个顶点u使得dis[u]是最⼩的。

(可以认为是贪⼼操作)2.u标记为已确定最短路径的点3.与u相连的每个没有被确定最短路径的顶点进⾏松弛操作。

算法思想:我们把点分为两类,⼀类是已确定最短路径的点,称为“⽩点”,另⼀类是未确定最短路径的点,称为“蓝点”。

如果我们要求出⼀个点的最短路径,就是把这个点由蓝点变为⽩点。

从起点到蓝点的最短路径上的中转点在这个时刻只能是⽩点。

Dijkstra的算法思想,就是⼀开始将起点到起点的距离标记为0,⽽后进⾏n次循环,每次找出⼀个到起点距离dis[u]最短的点u,将它从蓝点变为⽩点。

acm

acm
极大独立集:若独立集I 中增加任一个除I 集外的顶点后I 不是独立集。
完全二分图
最佳匹配:权和最大的匹配。
完全匹配(完备匹配):如果一个匹配中,图中的每个顶点都和图中某条边相关联。
1.2 独立集、覆盖集、支配集之间关系
(1)一个独立集是极大独立集,当且仅当它是一个支配集;
(2)I 是独立集,当且仅当G 中除I 集外的所有顶点是一个覆盖集;
g[v][u] = 1; //恢复可访问标志
}
else
{
if(c[v] < 0) //若顶点为灰色
{
if(l[v] < l[u]) //u 与v 相连
l[u] = l[v];
gc[u][v] = 2; //反向边
}
else //黑色
{
if(d[v] > d[u]) gc[u][v] = 3; //正向边
{
int i, j, k;
for(i = 2; i <= n; i++)
d[i] = 10000000000;
for(k = 1; k < n; k++)
for(i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
relax(i, j); //对每条边松弛
int graph[50][50];
int degree[50];
vector<int> path; //存储欧拉路
int n;
void FindCircuit(int u)
{
if(degree[u] == 0)

ACM培训资料数据结构和算法

ACM培训资料数据结构和算法

初 始 化 邻 接 矩 阵 arcs, 将 所 有 边 上 的 权 值 置 为 ∞
读 入 边 (v1 ,v2 )和 权 值 w
根 据 顶 点 v 1 ,v 2 查 找 顶 点 向 量 , 确 定 其 存 储 位 置 i,j
令 : G .a rc s [i][j].a d j= w ,若 有 相 关 信 息 , 输 入 弧 的 相 关 信 息 到 In fo ; 令 G .a rc s [j][i].a d j= w
2020/4/9
27
7.3.2 广度优先搜索 BFS
1)基本思想:
– 任选图中一个顶点 v ,访问此顶点,并作访问 标记。
– 从 v 出发,依次访问 v 的各个未曾被访问过的 邻接顶点 w1, w2, …, wt,并作访问标记。
– 然后再顺序访问 w1, w2, …, wt 的所有还未被访 问过的邻接顶点,并作访问标记。
N 已 读 入 arcnum 条 边 了 吗 ? Y
结束
13
7.2.2 邻接表 (Adjacency
1) 存储特点
List)
– 对于图G中的每个顶点vi,把所有邻接于vi的顶点vj链成一 个单链表,这个单链表称为顶点vi的邻接表;
– 将所有点的邻接表表头放到数组中,就构成了图的邻接表
2020/4/9
}Mgragh; /*Maragh是以邻接矩阵存储的图*/
2020/4/9
12
4)图的创建
创建以邻接矩阵存储的无向网
▪ 思路: 输 入 图 中 边 的 数 目 arcnum , 顶 点 数 目 vexnum
2020/4/9
依 次 读 入 vexnum 个 顶 点 信 息 , 存 入 顶 点 向 量

ACM暑期培训课程图论.ppt

ACM暑期培训课程图论.ppt

E问题
OUTPUT FORMAT
输出应当有F+1行,每行一个整数,依次表示路径经 过的顶点号。注意数据可能有多组解,但是只有上面题目 要求的那一组解是认为正确的。
SAMPLE OUTPUT(fence.out) 1 2 3 4 2 5 4 6 5 7
E问题
很显然,这是一个欧拉路径问题,我们要做的就是读入栅栏的 构图后,找到图中的一条欧拉路径。
图的连通性
4. 有向图的强连通分支
在下面的几页中,我们可以看到求图的 强连通分支的实例。
首先,图(a)为有向图G,其中的阴影部 分是G的强连通分支,在对图G进行DFS 的过程中,我们对每个顶点都标出了其 开始搜索时刻preOrder与完成时刻 postOrder,黑色边为DFS搜索树树枝;
可以看到,图G共有 4个强连通分支:
{a,b,e}
{c,d}
{f,g}
{h}
图的连通性
4. 有向图的强连通分量
(b)图中G的转置图G*。图中说明了求 强连通分支算法第3部计算出的深度优 先树,其中黑色边是树枝。每个强连通
子图对应于一棵深度优先树。图中黑色 顶点b,c,g和h是强连通子图中每个顶点 的祖先,这些顶点也是对G*进行深度 优先搜索所产生的深度优先树的树根。
int map[MAXV][MAXV]; //map[i][j]记录顶点i和顶点j之 间的路径数目
int deg[MAXV]; int path[MAXE]; 径
//deg[i]记录顶点i的度数 //path数组用来存放找到的欧拉路
int fn,minv,maxv,pathnum=0; //minv为顶点最小编号,maxv为顶点最大编号
G有欧拉回路(G为欧拉图):G连通,G中均为偶度顶点。

ACM常见算法

ACM常见算法

ACM常见算法ACM算法⼀、数论算法 1.求两数的最⼤公约数 2.求两数的最⼩公倍数 3.素数的求法 A.⼩范围内判断⼀个数是否为质数: B.判断longint范围内的数是否为素数(包含求50000以内的素数表):⼆、图论算法1.最⼩⽣成树A.Prim算法:B.Kruskal算法:(贪⼼) 按权值递增顺序删去图中的边,若不形成回路则将此边加⼊最⼩⽣成树。

2.最短路径 A.标号法求解单源点最短路径: B.Floyed算法求解所有顶点对之间的最短路径: C. Dijkstra 算法:3.计算图的传递闭包4.⽆向图的连通分量 A.深度优先 B 宽度优先(种⼦染⾊法)5.关键路径⼏个定义:顶点1为源点,n为汇点。

a. 顶点事件最早发⽣时间Ve[j], Ve [j] = max{ Ve [j] + w[I,j] },其中Ve (1) = 0; b. 顶点事件最晚发⽣时间 Vl[j], Vl [j] = min{ Vl[j] – w[I,j] },其中 Vl(n) = Ve(n); c. 边活动最早开始时间 Ee[I], 若边I由<j,k>表⽰,则Ee[I] = Ve[j]; d. 边活动最晚开始时间 El[I], 若边I由<j,k>表⽰,则El[I] = Vl[k] – w[j,k]; 若 Ee[j] = El[j] ,则活动j为关键活动,由关键活动组成的路径为关键路径。

求解⽅法: a. 从源点起topsort,判断是否有回路并计算Ve; b. 从汇点起topsort,求Vl; c. 算Ee 和 El;6.拓扑排序找⼊度为0的点,删去与其相连的所有边,不断重复这⼀过程。

例寻找⼀数列,其中任意连续p项之和为正,任意q 项之和为负,若不存在则输出NO.7.回路问题 Euler回路(DFS) 定义:经过图的每条边仅⼀次的回路。

(充要条件:图连同且⽆奇点) Hamilton回路定义:经过图的每个顶点仅⼀次的回路。

ACM算法讲解

ACM算法讲解
搜索 约10% 计算几何 约5% 动态规划 约15% 约20% 贪心 约5% 约5% 构造 图论
约5% 约10% 其它 约25%
5
纯数学题 数据结构
图作为一种非线性结构,被广泛应用于多个技术 领域。这一部分将是最难理解的,我们将先从基础知 识的讲解开始。
6
图论相关主题
• • • • • 第一阶段——图的遍历 第二阶段——最小生成树 第三阶段——最短路径 第四阶段:如果Vi和Vk为当前端结点,且 Vi在Vk之前被访问,则Vi的所有未被访问的邻接点 应在Vk的所有未被访问的邻接点之前访问。重复 (3),直到所有端结点均没有未被访问的邻接点
为止。 若此时还有顶点未被访问,则选一个未被访问
的顶点作为起始点,重复上述过程,直至所有顶点
均被访问过为止。
17
小鼠迷宫问题
小鼠a与小鼠b身处一个m×n的迷宫 中,如图所示。每一个方格表示迷宫中 的一个房间。这m×n个房间中有一些房 间是封闭的,不允许任何人进入。在迷 宫中任何位置均可沿上,下,左,右4个 方向进入未封闭的房间。小鼠a位于迷宫 的(p,q)方格中,它必须找出一条通向小 鼠b所在的(r,s)方格的路。请帮助小鼠a 找出所有通向小鼠b的最短道路。

【粗略分析】 以回溯方法(试探法)和图的广度优先搜索 法(路径最短的最优解)求解迷宫的路径,然后 用回溯从终点走回去,只有四周的点回合数为当 前点回合数-1时方为可能路径, 最后返回路径为1时说明一条路径已完成,计数 并返回,走下一条路径……
21
• #include<stdio.h> #define N 60 int s,map[N+1][N+1]; typedef struct{ int x,y; }xy; xy queue[N*N],start,end,last;

ACM基础算法入门

ACM基础算法入门


辗转相除法


扩展欧几里得
双六 一个双六上面有向前向后无限延续的格子,每个格子都写有整数。其中0号格子 是起点,1号格子是终点。而骰子上只有 a , b , -a , -b 四个整数,所以根据 a 和 b 的值的不同,有可能无法到达终点。 格子如下: …… -4 -3 -2 -1 0 1 2 3 4 …… 掷出四个整数各多少次可以到达终点?输出任意一组解。 1<= a , b <=10^9

0 1 0 0 1
解题过程

本题是简单的搜索问题,采用深度优先 遍历可以解决,根据题目要求,假设从 任意一点值为'1'的出发,将这点的坐标 上下左右全部用'0'替换,1次DFS后与初 始动这个'1'连接的'1'全部被替换成'0', 因此,直到图中不再存在'1'为至,总共 进行的DFS的次数就是最后的结果咯!那 么,根据题目要求,有4个方向,时间复 杂度为O(4*n*m)。
例题:

水池数目 南阳理工学院校园里有一些小河和一些湖泊,现在,我们把它们通一看成水池, 假设有一张我们学校的某处的地图,这个地图上仅标识了此处是否是水池,现在, 你的任务来了,请用计算机算出该地图中共有几个水池。 输入m行每行输入n个数,表示此处有水还是没水 (1表示此处是水池,0表示此处是地面) 0<m<100 0<n<100 输入: 34 1000 0011 1110 输出: 2 输入: 55 1111 0010 0000 1110 0011 输出: 3
把各区间按照a从小到大顺序。如果区间1的起点不是s, 则无解,即[s,t]无法被完全覆盖(因为其他区间的起点更大, 不可能覆盖到s点),否则选择起点在s的最长区间。选择此 区间[ai,bi]后,新的起点应该被设置为bi,并且忽略所有区间在 bi之前的部分,就像预处理一样。虽然贪心策略比上面的题 复杂,但是仍然只需要一次扫描。如下图5所示。s为当前有 效起点(此前部分已被覆盖),则应该选择区间2。

北京大学 acm程序设计 图论讲义

北京大学 acm程序设计 图论讲义
22
for (w=G->first(v); w<G->n(); w = G>next(v,w))
if (G->getMark(w) == UNVISITED) { G->setMark(w, VISITED); Q->enqueue(w); }
PostVisit(G, v); // Take action }}
Q Q
31
() ((1,1)) ((1,1) (2,3)) ((1,1) (2,4)) ((1,1) (2,4) (3.2))
Q Q
Q
32
() ((1,1)) ((1,1) (2,3)) ((1,1) (2,4)) ((1,1) (2,4) (3.2))
Q Q
33
Q () ((1,1)) ((1,1) (2,3)) ((1,1) (2,4)) ((1,1) (2,4) (3.2))
求解算法
穷举法 贪心法 深度/广度优先搜索
图和树的搜索 回溯法(深度优先)
递归
分治
动态规划法
55
谢谢!
56
49
动态规划法的思想
自底向上构造 在原问题的小子集中计算 每一步列出局部最优解,并用一张
表保留这些局部最优解,以避免重 复计算 子集越来越大,最终在问题的全集 上计算,所得出的就是整体最优 解。
50
Fib(1)=Fib(2)=1
Fibonacci数列 Fib(n)=Fib(n-1) + Fib (n-2)
23
八数码 深度优先搜索
1
23 184 765
2
c
3
283 164 75
283 14 765

ACM算法 计算几何基础ppt课件

ACM算法 计算几何基础ppt课件

57 2020/4/15
58 2020/4/15
59 2020/4/15
60 2020/4/15
61 2020/4/15
62 2020/4/15
63 2020/4/15
64 2020/4/15
特别提醒:
以上介绍的线段的三个属性, 是计算几何的基础,在很多方 面都有应用,比如求凸包等等, 请务必掌握!
15 2020/4/15
第二单元
多边形面积 和重心
16 2020/4/15
基本问题(1):
给定一个简单多边形,求其 面积。
输入:多边形(顶点按逆时 针顺序排列)
输出:面积S
17 2020/4/15
A=sigma(Ai) (i=1…N-2)
P1
A1 P2
P6 A4
P5 A3
A2 P4
P3
25 2020/4/15
凹多边形的面积?
P3
P2 P4
P1
26 2020/4/15
依然成立!!!
多边形面积公式:A=sigma(Ai) (i=1…N-2)
结论: “有向面积”A比“面积”S其实更本
质!
27 2020/4/15
思考如下图形:
18 2020/4/15
Any good idea?
19 2020/4/15
先讨论最简单的多边形——三角形
20 2020/4/15
三角形的面积:
在解析几何里, △ABC的面积可以通过 如下方法求得:
点坐标 => 边长 => 海伦公式 => 面积
21 2020/4/15
思考:此方法的缺点:
C=sigma((↑Pi +↑Pi+1)(↑Pi ×↑Pi+1) ) /(6A)
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
用归纳法,假设prim的前k步选出来的边e_1,…, e_k是最优解的一部分,用类似的方法证明prim的方法 选出的e_k+1 一定也能构造出最优解
代码示例
#define typec int // type of cost
const typec inf = 0x3f3f3f3f; // max of cost
无向图O(4m+n) 对稀疏图可以减少存储空间 可以直接访问到一个点的相邻结点 图的信息一般都不做修改
图的存储方式—邻接表
邻接表使用场合
顶点数很多n>1000,边数却不多。
采用邻接表存储后,很多算法的复杂度也都 是跟边数有关。
连通性的问题很多情况边数不多,多采用邻 接表存储方式
邻接表code
struct edge {
int x, y, nxt; typec c; } bf[E];
void addedge(int x, int y, typec c) {
bf[ne].x = x; bf[ne].y = y; bf[ne].c = c; bf[ne].nxt = head[x]; head[x] = ne++; }
for (i=1; i<n; i++) lowc[i] = cost[0][i];
for (i=1; i<n; i++) {
minc = inf; p = -1;
for (j=0; j<n; j++)
if (0 == vis[j] && minc > lowc[j]) {
minc = lowc[j]; p = j;
int vis[V]; typec lowc[V];
ቤተ መጻሕፍቲ ባይዱ
typec prim(typec cost[][V], int n) // vertex: 0 ~ n-1
{
int i, j, p;
typec minc, res = 0;
memset(vis, 0, sizeof(vis));
vis[0] = 1;
图的存储方式—邻接矩阵
邻接矩阵使用场合
数据规模不大n <= 1000,m越大越好 稠密图最好用邻接矩阵 图中不能有多重边出现 在做网络流类型的题目时候多采用邻接
矩阵,因为网络流的复杂度高,本身就 要求数据规模不能太大,并且需要频繁 地更新矩阵中的数据。
图的存储方式—邻接表
邻接表
mp[i]用链表的方式存储顶点i的相邻结点 空间复杂度:有向图O(2m+n)
算法思想
1.从有向图中选取一个没有前驱的顶 点,并输出之;
2.从有向图中删去此顶点以及所有以 它为尾的弧;
重复上述两步,直至图空,或者图不 空但找不到无前驱的顶点为止。没有前 驱 -- 入度为零,删除顶点及以它为尾的 弧-- 弧头顶点的入度减1。
根据算法思想: 找到的点的顺序依次为v6 , v1 , v4 , v3 , v2 , v5 (注意一边输出当前点,一边更新其他点的入度)
}
克鲁斯卡尔算法
kruskal 算法思想:贪心选取最短的边来 组成一棵最小的生成树。
具体做法:先将所有的边做排序,然后 利用并查集作判断来优先选择较小的边, 直到建成一棵生成树。
克鲁斯卡尔算法示例代码(a)
struct Msg//定义边结构体 { int s , e; int length; }Line[6000]; int FindFather(int v)//并查集 { if(father[v] == v) return v; else father[v] = FindFather(father[v]); return father[v]; }
图论的基础算法小结
By yesterday @ BJTU
部分内容摘自HH的PPT
目录
图的存储 拓扑排序 最小生成树 最短路 强连通分量
图的存储——邻接矩阵
邻接矩阵
g[i][j] 表示顶点i和顶点j的边关系
是否有边相连 边权值
空间复杂度:O(n^2) 访问速度快、直观、适合稠密
}
if (inf == minc) return -1; // 原图不连通
res += minc; vis[p] = 1;
for (j=0; j<n; j++)
if (0 == vis[j] && lowc[j] > cost[p][j])
lowc[j] = cost[p][j];
}
return res;
拓扑排序的使用
判断一个有向图中是否有环。无环的图 所有点都能进行拓扑排序。
类似于课程安排问题的题目
拓扑排序代码示例
int Find()//找零入度点 {
for(int i = 0 ;i < n; ++ i) if(!Vis[i] && G[i]->degree == 0) { Vis[i] = 1; Grap *p = G[i]->next; while(p) {//更新其他节点 p->degree -- ; p = p->next; } return i; }
图的遍历方式
按照某种顺序访问图中的所有顶点, 这样的操作较遍历。常用的遍历方 式有: 深度优先遍历DFS 广度优先遍历BFS
拓扑排序
概念引入: 一个工程常被分为多个小的子工程,这 些子工程被称为活动(Activity),在有向 图中若以顶点表示活动,有向边表示活 动之间的先后关系,这样的图简称为 AOV网。在AOV网中为了更好地完成工程, 必须满足活动之间先后关系,需要将各 活动排一个先后次序即为拓扑排序。
了floyd,也可以试一下)
最小生成树
prim 算法(复杂度O(n^2) kruskal算法复杂度O(m*lg(m)) 对于不同问题可以选择不同算法
Prim 算法证明
首先,一定有一个最优解包含了权值最小的边e_1 (prim的第一步),因为如果不是这样,那么最优的 解不包含e_1,把e_1加进去会形成一个环,任意去掉 环里比e_1权值大的一条边,这样就构造了更优的一个 解,矛盾。
return -1; }
void TopSort() {
for(int i = 0 ;i < n; ++ i) printf(“%d ” , Find());//输出拓扑排序结果
}
拓扑排序习题
校赛第四题(我没找到题号) 去年武汉区域赛第二题(可以到uva去刷
) Poj 1094(先用拓扑排序刷一下,等讲
相关文档
最新文档