图论类型各题总结-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; }

图论常考知识点总结

图论常考知识点总结

图论常考知识点总结1. 图的基本概念图是由顶点集合和边集合构成的。

顶点之间的连接称为边,边可以有方向也可以没有方向。

若图的边没有方向,则称图为无向图;若图的边有方向,则称图为有向图。

图的表示方式:邻接矩阵和邻接表。

邻接矩阵适合存储稠密图,邻接表适合存储稀疏图。

2. 图的连通性连通图:如果图中任意两点之间都存在路径,则称该图是连通图。

强连通图:有向图中,任意两个顶点之间都存在方向相同的路径,称为强连通图。

弱连通图:有向图中,去掉每条边的方向之后,所得到的无向图是连通图,称为弱连通图。

3. 图的遍历深度优先搜索(DFS):从起始顶点出发,沿着一条路往前走,走到不能走为止,然后退回到上一个分支点,再走下一条路,直到走遍图中所有的顶点。

广度优先搜索(BFS):从起始顶点出发,先访问它的所有邻居顶点,再按这些邻居顶点的顺序依次访问它们的邻居顶点,依次类推。

4. 最短路径狄克斯特拉算法:用于计算图中一个顶点到其他所有顶点的最短路径。

弗洛伊德算法:用于计算图中所有顶点之间的最短路径。

5. 最小生成树普里姆算法:用于计算无向图的最小生成树。

克鲁斯卡尔算法:用于计算无向图的最小生成树。

6. 拓扑排序拓扑排序用于有向无环图中对顶点进行排序,使得对每一条有向边(u,v),满足排序后的顶点u在顶点v之前。

以上就是图论中一些常考的知识点,希望对大家的学习有所帮助。

当然,图论还有很多其他的知识点,比如欧拉图、哈密顿图、网络流等,这些内容都值得我们深入学习和探讨。

图论在实际应用中有着广泛的应用,掌握好图论知识对于提升计算机科学和工程学的技能水平有着重要的意义。

acm竞赛知识点

acm竞赛知识点

acm竞赛知识点
以下是ACM竞赛的主要知识点:
1、基础算法:
排序算法(如快速排序、归并排序)
搜索算法(如二分搜索)
递归与分治算法
2、图论:
最短路径算法(如Dijkstra算法、Bellman-Ford算法)最小生成树算法(如Prim算法、Kruskal算法)
拓扑排序
图的遍历(深度优先搜索DFS、广度优先搜索BFS)
3、动态规划:
背包问题
最长公共子序列(LCS)
最长递增子序列(LIS)
矩阵链乘法
4、数据结构:
栈和队列
链表和树的基本操作
哈希表
并查集
5、计算几何:
点和向量的基本运算
线段相交判定
凸包算法
6、字符串处理:
字符串匹配算法(如KMP、Boyer-Moore)后缀数组
字符串编辑距离
7、数论:
质数判定
最大公约数和最小公倍数
快速幂
8、图的高级算法:
最大流算法(如Ford-Fulkerson算法)二分图匹配
最小割算法
9、动态规划优化:状态压缩
斜率优化
记忆化搜索
10、其他:
模拟和贪心算法
数学问题
网络流问题。

ACM图论基础算法概论

ACM图论基础算法概论
用归纳法,假设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];

acm构造题

acm构造题

acm构造题
当谈到构造题时,有许多不同类型的ACM构造问题。

以下是一些常见的ACM构造题目类型和解决方法:
1.排列组合构造:这类问题通常要求你构造一个满足某种条件的排列或组合。

解决这类问题的关键是理解条件并找到一种满足条件的构造方法。

可以使用递归、迭代或其他数学技巧来解决这类问题。

2.图论构造:这类问题涉及到构建满足某些图论性质的图。

常见的图论构造问题包括树的构造、连通图的构造、二分图的构造等。

解决这类问题通常需要理解图论的基本概念和性质,并使用合适的算法进行构造。

3.数据结构构造:这类问题要求你构造一个满足某种数据结构性质的数据结构。

例如,构造一个满足平衡二叉搜索树性质的树,或者构造一个满足堆性质的数组。

解决这类问题通常需要对特定数据结构的性质和操作进行了解,并设计相应的构造方法。

4.数学构造:这类问题要求你构造一个满足某种数学性质的对象。

例如,构造一组满足特定方程的整数,或者构造一种满足特定性质的数列。

解决这类问题通常需要运用数学知识和技巧,并找到合适的构造方法。

对于ACM构造题目,关键是理解问题的要求和条件,并设计一个满足条件的构造方法。

可以根据问题的性质选择适当的算法、数据结构或数学技巧来解决问题。

在解题过程中,需要注意时间复杂度和空间复杂度的控制,以确保算法的效率和正
确性。

另外,多进行思维训练和练习,熟悉不同类型的构造问题,能够提高解决问题的能力。

acm贪心算法经典题型归纳

acm贪心算法经典题型归纳

acm贪心算法经典题型归纳
贪心算法是一种在求解最优化问题时常用的算法思想,它通常
用于解决那些具有最优子结构性质的问题。

在ACM竞赛中,贪心算
法经典题型主要包括以下几类:
1. 区间调度问题,这类问题要求在一系列区间中选择尽量多的
不重叠区间。

经典问题包括最大不重叠区间数量、最小区间覆盖等。

2. 背包问题,在给定背包容量和一系列物品的重量、价值的情
况下,选择装入背包的物品,使得背包内物品的总价值最大。

贪心
算法通常用于解决部分背包问题或者分数背包问题。

3. 最小生成树,贪心算法经典的应用之一是求解最小生成树,
其中Prim算法和Kruskal算法就是典型的贪心算法。

4. 最短路径问题,在有向图或者无向图中,求解起点到终点的
最短路径。

Dijkstra算法和Bellman-Ford算法都可以使用贪心思
想进行优化。

5. 哈夫曼编码,贪心算法还可以用于构造哈夫曼树,实现数据
的最优编码。

以上仅是贪心算法在ACM竞赛中的一些经典题型,实际上贪心算法还可以应用于很多其他问题的求解中。

在解决这些问题时,需要注意贪心选择性质和最优子结构性质,合理选择贪心策略,并证明其正确性。

同时,也需要注意到贪心算法并不适用于所有问题,有时候需要结合动态规划等其他算法来求解。

希望这些信息对你有帮助。

大一acm竞赛试题及答案

大一acm竞赛试题及答案

大一acm竞赛试题及答案一、选择题(每题5分,共20分)1. 下列哪个算法的时间复杂度为O(n^2)?A. 快速排序B. 归并排序C. 插入排序D. 冒泡排序答案:C2. 在C++中,下列哪个关键字用于定义类?A. structB. classC. unionD. enum答案:B3. 下列哪个数据结构适合用于实现稀疏矩阵?A. 顺序存储B. 链式存储C. 压缩存储D. 散列存储答案:C4. 在图论中,下列哪个算法用于寻找最短路径?A. 深度优先搜索B. 广度优先搜索C. 迪杰斯特拉算法D. 弗洛伊德算法二、填空题(每题5分,共20分)1. 在二叉树的遍历算法中,______遍历会先访问根节点。

答案:前序2. 哈希表的冲突解决方法之一是______。

答案:链地址法3. 在数据库中,用于实现一对多关系的表结构是______。

答案:外键4. 动态规划算法的核心是______。

答案:状态转移方程三、编程题(每题30分,共60分)1. 编写一个函数,实现对一个整数数组进行排序,并返回排序后的数组。

答案:```pythondef sort_array(arr):arr.sort()return arr```2. 编写一个函数,实现计算给定整数n的阶乘。

答案:```pythondef factorial(n):if n == 0:return 1return n * factorial(n - 1)```四、算法题(每题30分,共30分)1. 给定一个整数数组,请设计一个算法找出数组中第二大的数。

答案:```pythondef find_second_max(nums):first_max = second_max = float('-inf')for num in nums:if num > first_max:second_max = first_maxfirst_max = numelif num > second_max and num != first_max:second_max = numreturn second_max```。

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常用算法及其相应的练习题

ACM常用算法及其相应的练习题2007-12-03 23:48OJ上的一些水题(可用来练手和增加自信)(poj3299,poj2159,poj2739,poj1083,poj2262,poj1503,poj3006,poj2255,poj3 094)初期:一.基本算法:(1)枚举. (poj1753,poj2965)(2)贪心(poj1328,poj2109,poj2586)(3)递归和分治法.(4)递推.(5)构造法.(poj3295)(6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法:(1)图的深度优先遍历和广度优先遍历.(2)最短路径算法(dijkstra,bellman-ford,floyd,heap+dijkstra)(poj1860,poj3259,poj1062,poj2253,poj1125,poj2240)(3)最小生成树算法(prim,kruskal)(poj1789,poj2485,poj1258,poj3026)(4)拓扑排序 (poj1094)(5)二分图的最大匹配 (匈牙利算法) (poj3041,poj3020)(6)最大流的增广路算法(KM算法). (poj1459,poj3436)三.数据结构.(1)串 (poj1035,poj3080,poj1936)(2)排序(快排、归并排(与逆序数有关)、堆排) (poj2388,poj2299)(3)简单并查集的应用.(4)哈希表和二分查找等高效查找法(数的Hash,串的Hash)(poj3349,poj3274,POJ2151,poj1840,poj2002,poj2503)(5)哈夫曼树(poj3253)(6)堆(7)trie树(静态建树、动态建树) (poj2513)四.简单搜索(1)深度优先搜索 (poj2488,poj3083,poj3009,poj1321,poj2251)(2)广度优先搜索(poj3278,poj1426,poj3126,poj3087.poj3414)(3)简单搜索技巧和剪枝(poj2531,poj1416,poj2676,1129)五.动态规划(1)背包问题. (poj1837,poj1276)(2)型如下表的简单DP(可参考lrj的书 page149):1.E[j]=opt{D+w(i,j)} (poj3267,poj1836,poj1260,poj2533)2.E[i,j]=opt{D[i-1,j]+xi,D[i,j-1]+yj,D[i-1][j-1]+zij} (最长公共子序列)(poj3176,poj1080,poj1159)3.C[i,j]=w[i,j]+opt{C[i,k-1]+C[k,j]}.(最优二分检索树问题)六.数学(1)组合数学:1.加法原理和乘法原理.2.排列组合.3.递推关系.(POJ3252,poj1850,poj1019,poj1942)(2)数论.1.素数与整除问题2.进制位.3.同余模运算.(poj2635, poj3292,poj1845,poj2115)(3)计算方法.1.二分法求解单调函数相关知识.(poj3273,poj3258,poj1905,poj3122)七.计算几何学.(1)几何公式.(2)叉积和点积的运用(如线段相交的判定,点到线段的距离等).(poj2031,poj1039)(3)多边型的简单算法(求面积)和相关判定(点在多边型内,多边型是否相交)(poj1408,poj1584)(4)凸包. (poj2187,poj1113)中级:一.基本算法:(1)C++的标准模版库的应用. (poj3096,poj3007)(2)较为复杂的模拟题的训练(poj3393,poj1472,poj3371,poj1027,poj2706)二.图算法:(1)差分约束系统的建立和求解. (poj1201,poj2983)(2)最小费用最大流(poj2516,poj2516,poj2195)(3)双连通分量(poj2942)(4)强连通分支及其缩点.(poj2186)(5)图的割边和割点(poj3352)(6)最小割模型、网络流规约(poj3308, )三.数据结构.(1)线段树. (poj2528,poj2828,poj2777,poj2886,poj2750)(2)静态二叉检索树. (poj2482,poj2352)(3)树状树组(poj1195,poj3321)(4)RMQ. (poj3264,poj3368)(5)并查集的高级应用. (poj1703,2492)(6)KMP算法. (poj1961,poj2406)四.搜索(1)最优化剪枝和可行性剪枝(2)搜索的技巧和优化 (poj3411,poj1724)(3)记忆化搜索(poj3373,poj1691)五.动态规划(1)较为复杂的动态规划(如动态规划解特别的施行商问题等)(poj1191,poj1054,poj3280,poj2029,poj2948,poj1925,poj3034)(2)记录状态的动态规划. (POJ3254,poj2411,poj1185)(3)树型动态规划(poj2057,poj1947,poj2486,poj3140)六.数学(1)组合数学:1.容斥原理.2.抽屉原理.3.置换群与Polya定理(poj1286,poj2409,poj3270,poj1026).4.递推关系和母函数.(2)数学.1.高斯消元法(poj2947,poj1487, poj2065,poj1166,poj1222)2.概率问题. (poj3071,poj3440)3.GCD、扩展的欧几里德(中国剩余定理) (poj3101)(3)计算方法.1.0/1分数规划. (poj2976)2.三分法求解单峰(单谷)的极值.3.矩阵法(poj3150,poj3422,poj3070)4.迭代逼近(poj3301)(4)随机化算法(poj3318,poj2454)(5)杂题.(poj1870,poj3296,poj3286,poj1095)七.计算几何学.(1)坐标离散化.(2)扫描线算法(例如求矩形的面积和周长并,常和线段树或堆一起使用).(poj1765,poj1177,poj1151,poj3277,poj2280,poj3004)(3)多边形的内核(半平面交)(poj3130,poj3335)(4)几何工具的综合应用.(poj1819,poj1066,poj2043,poj3227,poj2165,poj3429)高级:一.基本算法要求:(1)代码快速写成,精简但不失风格(poj2525,poj1684,poj1421,poj1048,poj2050,poj3306)(2)保证正确性和高效性. poj3434二.图算法:(1)度限制最小生成树和第K最短路. (poj1639)(2)最短路,最小生成树,二分图,最大流问题的相关理论(主要是模型建立和求解)(poj3155,poj2112,poj1966,poj3281,poj1087,poj2289,poj3216,poj2446(3)最优比率生成树. (poj2728)(4)最小树形图(poj3164)(5)次小生成树.(6)无向图、有向图的最小环三.数据结构.(1)trie图的建立和应用. (poj2778)(2)LCA和RMQ问题(LCA(最近公共祖先问题) 有离线算法(并查集+dfs) 和在线算法(RMQ+dfs)).(poj1330)(3)双端队列和它的应用(维护一个单调的队列,常常在动态规划中起到优化状态转移的目的). (poj2823)(4)左偏树(可合并堆).(5)后缀树(非常有用的数据结构,也是赛区考题的热点).(poj3415,poj3294)四.搜索(1)较麻烦的搜索题目训练(poj1069,poj3322,poj1475,poj1924,poj2049,poj3426)(2)广搜的状态优化:利用M进制数存储状态、转化为串用hash表判重、按位压缩存储状态、双向广搜、A*算法.(poj1768,poj1184,poj1872,poj1324,poj2046,poj1482)(3)深搜的优化:尽量用位运算、一定要加剪枝、函数参数尽可能少、层数不易过大、可以考虑双向搜索或者是轮换搜索、IDA*算法.(poj3131,poj2870,poj2286)五.动态规划(1)需要用数据结构优化的动态规划.(poj2754,poj3378,poj3017)(2)四边形不等式理论.(3)较难的状态DP(poj3133)六.数学(1)组合数学.1.MoBius反演(poj2888,poj2154)2.偏序关系理论.(2)博奕论.1.极大极小过程(poj3317,poj1085)2.Nim问题.七.计算几何学.(1)半平面求交(poj3384,poj2540)(2)可视图的建立(poj2966)(3)点集最小圆覆盖.(4)对踵点(poj2079)八.综合题.(poj3109,poj1478,poj1462,poj2729,poj2048,poj3336,poj3315,poj214 8,poj1263)--------------------------------------------------------------------以及补充Dp状态设计与方程总结1.不完全状态记录<1>青蛙过河问题<2>利用区间dp2.背包类问题<1> 0-1背包,经典问题<2>无限背包,经典问题<3>判定性背包问题<4>带附属关系的背包问题<5> + -1背包问题<6>双背包求最优值<7>构造三角形问题<8>带上下界限制的背包问题(012背包)3.线性的动态规划问题<1>积木游戏问题<2>决斗(判定性问题)<3>圆的最大多边形问题<4>统计单词个数问题<5>棋盘分割<6>日程安排问题<7>最小逼近问题(求出两数之比最接近某数/两数之和等于某数等等)<8>方块消除游戏(某区间可以连续消去求最大效益)<9>资源分配问题<10>数字三角形问题<11>漂亮的打印<12>邮局问题与构造答案<13>最高积木问题<14>两段连续和最大<15>2次幂和问题<16>N个数的最大M段子段和<17>交叉最大数问题4.判定性问题的dp(如判定整除、判定可达性等)<1>模K问题的dp<2>特殊的模K问题,求最大(最小)模K的数<3>变换数问题5.单调性优化的动态规划<1>1-SUM问题<2>2-SUM问题<3>序列划分问题(单调队列优化)6.剖分问题(多边形剖分/石子合并/圆的剖分/乘积最大)<1>凸多边形的三角剖分问题<2>乘积最大问题<3>多边形游戏(多边形边上是操作符,顶点有权值)<4>石子合并(N^3/N^2/NLogN各种优化)7.贪心的动态规划<1>最优装载问题<2>部分背包问题<3>乘船问题<4>贪心策略<5>双机调度问题Johnson算法8.状态dp<1>牛仔射击问题(博弈类)<2>哈密顿路径的状态dp<3>两支点天平平衡问题<4>一个有向图的最接近二部图9.树型dp<1>完美服务器问题(每个节点有3种状态)<2>小胖守皇宫问题<3>网络收费问题<4>树中漫游问题<5>树上的博弈<6>树的最大独立集问题<7>树的最大平衡值问题<8>构造树的最小环枚举法,常常称之为穷举法,是指从可能的集合中一一枚举各个元素,用题目给定的约束条件判定哪些是无用的,哪些是有用的。

acm编程例题 参考答案

acm编程例题 参考答案

acm编程例题参考答案ACM编程例题参考答案ACM(Advanced Computer Mathematics)是一种面向计算机科学与技术的竞赛形式,旨在提高参与者的编程技能和解决问题的能力。

ACM编程例题是指在ACM竞赛中出现的一系列编程题目,这些题目涵盖了各种算法和数据结构的应用。

本文将给出一些ACM编程例题的参考答案,希望能够帮助读者更好地理解和掌握这些题目的解法。

一、题目一:最大公约数题目描述:给定两个正整数a和b,求它们的最大公约数。

解题思路:最大公约数可以通过欧几里得算法来求解。

该算法的基本思想是,两个正整数的最大公约数等于其中较小的数和两数之差的最大公约数。

具体的实现可以使用递归或循环的方式。

代码示例:```c++int gcd(int a, int b) {if (b == 0) {return a;}return gcd(b, a % b);}```二、题目二:素数判断题目描述:给定一个正整数n,判断它是否为素数。

解题思路:素数是只能被1和自身整除的正整数。

判断一个数是否为素数可以使用试除法,即从2开始,依次判断n是否能被2到sqrt(n)之间的数整除。

如果存在能整除n的数,则n不是素数;否则,n是素数。

代码示例:```c++bool isPrime(int n) {if (n <= 1) {return false;}for (int i = 2; i * i <= n; i++) {if (n % i == 0) {return false;}}return true;}```三、题目三:字符串反转题目描述:给定一个字符串s,将其反转后输出。

解题思路:字符串反转可以通过将字符串的首尾字符依次交换来实现。

可以使用双指针的方式,一个指针指向字符串的首字符,另一个指针指向字符串的尾字符,然后交换两个指针所指向的字符,并向中间移动,直到两个指针相遇。

代码示例:```c++void reverseString(string& s) {int left = 0;int right = s.length() - 1;while (left < right) {swap(s[left], s[right]);left++;right--;}}```四、题目四:二分查找题目描述:给定一个有序数组和一个目标值,使用二分查找算法在数组中找到目标值的索引,如果目标值不存在,则返回-1。

acm大赛历年程序题

acm大赛历年程序题

acm大赛历年程序题ACM国际大学生程序设计竞赛(The ACM International Collegiate Programming Contest)是全球范围内最具声誉的大学生程序设计竞赛之一。

每年都有来自世界各地的顶尖大学参加这一比赛,他们将在规定的时间内解决一系列编程问题,以展示他们的算法和编程技巧。

历年来,ACM大赛的程序题目一直是各个大学的计算机科学学生学习和训练的重要素材。

ACM大赛历年程序题的设计旨在考察参赛者的算法设计与实现能力。

这些问题通常具有一定的难度,涵盖了多种算法和数据结构。

在ACM大赛中,选手需要在规定的时间内,根据给定的输入数据,编写程序解决问题,并输出正确的结果。

ACM大赛历年程序题通常分为多个分类,下面将列举几个常见的分类及其特点:1. 图论问题:图论是ACM大赛中常见的题目类型之一。

这类问题涉及到对图的建模和算法设计。

参赛者需要熟悉常见的图观念和算法,如图的遍历、最短路径、最小生成树等。

2. 动态规划问题:动态规划是ACM大赛中常用的解决问题的方法之一。

动态规划问题通常需要设计状态转移方程,并根据之前已经计算过的结果来推导最优解。

这类问题要求选手具备良好的逻辑思维和数学推导能力。

3. 贪心算法问题:贪心算法是一种简单而高效的算法思想。

贪心算法问题一般需要选手根据问题的特性,每次都选择当前情况下最优的解决方案。

这类问题在实际应用中非常常见,选手需要能够灵活地运用贪心策略解决问题。

4. 字符串处理问题:字符串处理问题涉及到对字符串进行各种操作,如匹配、查找、替换等。

选手需要熟练掌握字符串的各种操作和常见算法,如KMP算法、Boyer-Moore算法等。

5. 数学问题:数学问题在ACM大赛中也是常见的题目类型。

这类问题通常涉及到各种数学公式和算法,如排列组合、素数判定、快速幂等。

选手需要具备扎实的数学知识和计算能力。

ACM大赛历年程序题的学习对于计算机科学学生来说是非常重要的。

acm试题及答案

acm试题及答案

acm试题及答案ACM试题及答案试题 1: 给定一个整数数组,请找出数组中第二大的数。

答案:1. 对数组进行排序。

2. 数组排序后,倒数第二个元素即为第二大的数。

试题 2: 编写一个函数,计算给定字符串中字符出现的次数。

答案:```pythondef count_characters(s):count_dict = {}for char in s:if char in count_dict:count_dict[char] += 1else:count_dict[char] = 1return count_dict```试题 3: 判断一个数是否为素数。

答案:1. 如果数小于2,则不是素数。

2. 从2开始到该数的平方根,检查是否有因数。

3. 如果没有因数,则该数是素数。

试题 4: 实现一个算法,将一个整数数组按照奇数在前,偶数在后的顺序重新排列。

答案:```pythondef rearrange_array(arr):odd = []even = []for num in arr:if num % 2 == 0:even.append(num)else:odd.append(num)return odd + even```试题 5: 给定一个链表,删除链表的倒数第n个节点。

答案:1. 遍历链表,找到链表的长度。

2. 再次遍历链表,找到倒数第n个节点的前一个节点。

3. 将前一个节点的next指针指向当前节点的下一个节点。

4. 如果当前节点是头节点,则更新头节点。

试题 6: 编写一个函数,实现字符串反转。

答案:```pythondef reverse_string(s):return s[::-1]```试题 7: 给定一个整数数组,找出数组中没有出现的最小正整数。

答案:1. 遍历数组,使用哈希表记录出现的数字。

2. 从1开始,检查每个数字是否在哈希表中。

3. 第一个不在哈希表中的数字即为答案。

试题 8: 实现一个算法,计算斐波那契数列的第n项。

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(肯德基、比萨饼、麦当劳)。

ACM图论解题报告

ACM图论解题报告

ACM图论解题报告图论1 题意:输入cas n m 输入n个数输入m组每组表示一个范围内l r 中小于num 的数的个数注意从l是0开始的思路:区间内找数很容易联想到划分树划分树是用来求一个区间内的第k 大的数那我们可以找出第1第2第3.。

大数的值和num进行比较用二分法很容易找到第几大的数小于且等于num_include_lt;stdio.h_gt;_include_lt;algorithm_gt;using namespace std;_define M 100005int tree[40][M],sorted[M];int toLeft[40][M];void build(int level,int left,int right){if(left==right)return ;int mid=(left+right)_gt;_gt;1;int i;int suppose;//假设在中位数sorted[mid]左边的数都全部小于sorted[mid] suppose=mid-left+1;for(i=left;i_lt;=right;i++){if(tree[level][i]_lt;sorted[mid]){suppose--;}}//如果suppose==1,则说明数组中值为sorted[mid]只有一个数。

比如序列:1 3 4 5 6,sorted[mid]=4/_如果suppose_gt;1,则说明数组中左半边值为sorted[mid]的不止一个数,为mid-suppose。

比如序列:1 4 4 4 6,sorted[mid]=4_/int lpos=left,rpos=mid+1;for(i=left;i_lt;=right;i++){if(i==left){//这里是预处理,相当与初始化toLeft[level][i]=0;}else{toLeft[level][i]=toLeft[level][i-1];}if(tree[level][i]_lt;sorted[mid]){//划分到中位数左边 toLeft[level][i]++;tree[level+1][lpos++]=tree[level][i];。

ACM必做50题的解题-二分图

ACM必做50题的解题-二分图

poj 1325 Machine Schedule(最小点覆盖->二分图最大匹配)题意:有两台机器A和B,分别有n种和m种不同的模式,有k个工作,每个工作都可以在那两个机器的某种特定的模式下处理。

如job0既可以在A机器的3好模式下处理,也可以在B 机器的4号模式下处理。

机器的工作模式改变只能通过人工来重启。

通过改变工作的顺序,和分配每个工作给合适的机器可以减少重启机器的次数达到最小。

任务就是计算那个最小的次数。

初始时两台机器都运行在0号模式下。

思路:把每个任务化为一条线,假设任务i在A机器上处理的模式为A[x]点,在B机器上为B[y]点,连接A[x]和B[y],用A机器和B机器中最少的点覆盖所有的边(用最少的模式完成所有的任务)。

这是最小点覆盖问题,根据König定理(一个二分图中的最大匹配数等于这个图中的最小点覆盖数)就是求的二分图的最大匹配,然后再用匈牙利算法直接就算出最大匹配数了,要注意的是初始是在0号模式下,所以如果A或B机器其中至少有个在0号模式下时就不用重启机器了,所以建图的时候没有把0建进去。

关于二分匹配在/u3/102624/showart.php?id=2060232#include <stdio.h>#include <string.h>#define N 105#define M 1005int g[N][N];int used[N], mat[N], flag[N];int min, n, m;/*寻找增广路径*/int find(int k){int i, j;for(i=1; i<=g[k][0]; i++){j = g[k][i];if(!used[j]){used[j] = 1;if(mat[j]==-1 || find(mat[j])){mat[j] = k;return 1;}}}return 0;}/*匈牙利算法*/void hungary(){int i;for(i=1; i<=n-1; i++){min += find(i);memset(used, 0, sizeof(used));}printf("%d\n", min);}int main(){int i, j;int k, a, b, c;while(scanf("%d", &n) && n){scanf("%d%d", &m, &k);memset(mat, -1, sizeof(mat));memset(g, 0, sizeof(g)); //一开始这个没有初始化,wa了好多次,搞好久==!for(i=0; i<k; i++){scanf("%d%d%d", &a, &b, &c);if(b != 0 && c != 0){g[b][++g[b][0]] = c; //邻接表}}min = 0;hungary();}}poj 1469 COURSES二分匹配问题:匈牙利算法实现(可以作为模板)//二分匹配中,两个集合不能存在交集#include <iostream>#include <string.h>#include <stdio.h>using namespace std;#define array1 101#define array2 301bool map[array1][array2]; //定义临界矩阵int final[array2];int match[array2];int p,n; //两个集合分别存储p个元素和n个元素int DFS(int p) //p为课程{int i;int t;//遍历所有的学生for(i=1;i<n+1;++i){if(map[p][i] && !final[i]){final[i] = 1;t= match[i];match[i]= p; //路径取反操作(原来在匹配中的边变成不在匹配中,不在的变成在每一次)if(t==0 || DFS(t)) return 1; //找到了一条增广路径match[i] = t;}}return 0; //没有找到增广路径}int mat(){int matchmax = 0; //matchmax为最大匹配数//遍历所有的课程for(i=1;i<p+1;++i){memset(final,0,sizeof(final)); //重新标记未访问,此处要注意if(DFS(i)) matchmax++;}return matchmax;}int main(){//freopen("1.txt","r",stdin);int t;int i,j,k;int temptcount;int stu;scanf("%d",&t);for(i=0;i<t;++i){memset(map,0,sizeof(map)); //对临界矩阵进行初始化memset(match,0,sizeof(match));scanf("%d%d",&p,&n);for(j=1;j<p+1;++j){scanf("%d",&temptcount);for(k=0;k<temptcount;++k){scanf("%d",&stu);map[j][stu] = 1;}}if(mat()==p) printf("YES\n");else printf("NO\n");}return 0;}POJ 2195 Going Home二分图最佳匹配,经典的KM算法#include <stdio.h>#include <string.h>const int MAXN = 200+5;const int INF = 1000000000;int N;int g[MAXN][MAXN];int pre[MAXN];int lx[MAXN], ly[MAXN], slack[MAXN],man[MAXN][2],ff[MAXN][2]; bool visx[MAXN], visy[MAXN];int abs(int a){if(a<0)return -a;return a;}bool dfs(int t){int i;visx[t] = true;for(i = 0; i < N; i++){if(visy[i]) continue;int tmp = lx[t]+ly[i]-g[t][i];if(tmp == 0){visy[i] = true;if(pre[i] == -1 || dfs(pre[i])){pre[i] = t;return true;}}else if(slack[i] > tmp){slack[i] = tmp;}}return false;}int KM(){int i, j, k;for(i = 0; i < N; i++)lx[i] = -INF;memset(ly, 0, sizeof(ly));memset(pre, -1, sizeof(pre));for(i = 0; i < N; i++)for(j = 0; j < N; j++)if(lx[i] < g[i][j])lx[i] = g[i][j];for(i = 0; i < N; i++){for(j = 0; j < N; j++) slack[j] = INF;while(1){memset(visx, false, sizeof(visx));memset(visy, false, sizeof(visy));if(dfs(i)) break;int d = INF;for(j = 0; j < N; j++)if(!visy[j] &&d > slack[j])d = slack[j];for(j = 0; j < N; j++){if(visx[j]) lx[j] -= d;if(visy[j]) ly[j] += d;else slack[j] -= d;}}}int ans = 0;for(i = 0; i < N; i++){if(pre[i] != -1)ans -= g[pre[i]][i];}return ans;}int main(){int h,v,mf,mm;// freopen("1.txt","r",stdin);scanf("%d%d",&h,&v);while(h!=0||v!=0){mm=mf=0;for(int i=0;i<h;i++)for(int j=0;j<v;j++){char c;scanf("%c",&c);while(c!='.'&&c!='H'&&c!='m')scanf("%c",&c);if(c=='H'){ff[mf][0]=i;ff[mf][1]=j;mf++;}if(c=='m'){man[mm][0]=i;man[mm][1]=j;mm++;}}N=mm;for(int i=0;i<N;i++)for(int j=0;j<N;j++)g[i][j]=-(abs(man[i][0]-ff[j][0])+abs(man[i][1]-ff[j][1]));printf("%d\n",KM());scanf("%d%d",&h,&v);}}POJ 2446 Chessboard算法:很囧的题,本来打算用搜索过的,发现深搜肯定超时,试了一下,果然超时。

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 的活动,而空白长条表 示的活动是当前正在检 查相容性的活动。
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

hdu4318 Power transmission 最短路当数据很大的时候的解决办法一道题目的解题全过程记录最短路解决大数据模拟链表Power transmissionTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 663 Accepted Submission(s): 231Problem DescriptionThe project West-East power transmission is famous around the world. It transmits the electricity from western areas to east China. There are many nodes in the power system. Each node is connected with several other nodes in the system by cable. Power can be only transmitted between two connected nodes. For each node, it can’t send power to two or more other nodes at the same time.As we have all known, power will be loss during the transmission. Bob is the chief engineer of the project. He wants to build a transmission line which send power from one node to another node and minimize the power loss at the same time. Now he asks you to help him solve the problem.InputThere are s everal test cases. For each test case, the first line contains an integer N (0 < N ≤ 50000) which represents the number of nodes in the power system. Then there will be N groups of data following. For the i-th(0 < i ≤ N) group, the first line is an integer ki (ki ≤ 50), which means the node i is connected with ki nodes. The rest of the i-th group data are divided into ki lines. Each line contains an integer ai (0 < ai ≤ N, ai ≠ i) and an integer bi (0 ≤ bi ≤ 100), which represents power can be transmitted from node i to ai and will loss bi% while transmitting. The last line of input data contains three integers separated by single spaces. The first one is s, the second is t (0 < s, t ≤ N), and the third is the total power M (0 < M ≤ 10^6) at node s.OutputFor each test case, output the minimum of loss power while transmitting from node s to node t. The result should be printed with two digits to the right of the decimal point. If power cannot be transmitted from node s to node t, output “IMPOSSIBLE!” in a line.Sample Input422 503 7021 304 2021 104 401 4 100Sample Output60.00HintIn the sample, the best transmission line is 1 -> 2 -> 4, loss power is 100 * 50% + 100 * (100%-50%)*20% = 60.00MicrosoftInternetExplorer402DocumentNotSpecified7.8Normal0题意:多个点从一个点往另一个点运输天然气但是从某点到另外一点是会有损耗的题中输入的即为损耗的百分数问从点s到t最少损耗多少分析: 很明显是最短路问题但是有个比较卡人的地方就是最多会有50000个点数据太大用map数组存不下会爆掉我们考虑到用链表就用了数组去模拟链表保存从当前点能到达的点队长把写解题报告的任务光荣的交给了我但是我对看代码表示相当的纠结所以就自己去写了个好理解把自己的贴上/*#include<stdio.h>#include<string.h>struct haha{int son[55]; //记录从当前点到其它能走到的点double son_val[55]; //记录从当前点到其它能走到的点的消耗int cnt;//记录存取的儿子个数}a[50100];int n,flag,s,t,M,used[50100];double min[50100];double find_short()//模拟以前数据比较小的时候的模板{int i,j,pos,cnt;double mm;memset(used,0,sizeof(used));for(i=1;i<=n;i++) min[i]=1;cnt=a[s].cnt;while(cnt--){min[a[s].son[cnt]]=a[s].son_val[cnt];}used[s]=1;min[s]=0;for(i=2;i<=n;i++){mm=1;for(j=1;j<=n;j++){if(!used[j]&&mm>min[j]){pos=j;mm=min[j];}}if(mm==1) {flag=1;return 0;}used[pos]=1;cnt=a[pos].cnt;for(j=0;j<cnt;j++){if(!used[a[pos].son[j]]&&min[pos]+(1.0-min[pos])*a[pos].son_val[j]<min[a[pos].son[j]])min[a[pos].son[j]]=min[pos]+(1.0-min[pos])*a[pos].son_val[j];}if(pos==t) return min[t];//这里很重要不加会超时的哦}return min[t];}int main(){int i,m,x,y;double val,k;while(scanf("%d",&n)!=EOF){flag=0;for(i=1;i<=n;i++)a[i].cnt=0;for(i=1;i<=n;i++){scanf("%d",&m);while(m--){scanf("%d %d",&x,&y);val=y/100.0;a[i].son[a[i].cnt]=x;a[i].son_val[a[i].cnt++]=val;}}scanf("%d %d %d",&s,&t,&M);k=find_short();if(flag==1) {printf("IMPOSSIBLE!\n");continue;}printf("%.2lf\n",k*M);}return 0;}*/hdu1596 find the safest road 最短路也能求最大值分类:图论2012-07-27 23:21177人阅读评论(0)收藏编辑删除find the safest roadTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 2477 Accepted Submission(s): 978Problem DescriptionXX 星球有很多城市,每个城市之间有一条或多条飞行通道,但是并不是所有的路都是很安全的,每一条路有一个安全系数s,s是在0 和 1 间的实数(包括0,1),一条从u 到v 的通道P 的安全度为Safe(P) = s(e1)*s(e2)…*s(ek) e1,e2,ek是P 上的边,现在8600 想出去旅游,面对这这么多的路,他想找一条最安全的路。

但是8600 的数学不好,想请你帮忙^_^Input输入包括多个测试实例,每个实例包括:第一行:n。

n表示城市的个数n<=1000;接着是一个n*n的矩阵表示两个城市之间的安全系数,(0可以理解为那两个城市之间没有直接的通道)接着是Q个8600要旅游的路线,每行有两个数字,表示8600所在的城市和要去的城市Output如果86无法达到他的目的地,输出"What a pity!",其他的输出这两个城市之间的最安全道路的安全系数,保留三位小数。

Sample Input31 0.5 0.50.5 1 0.40.5 0.4 131 22 31 3Sample Output0.5000.4000.500Authorailyanlu#include<stdio.h>#include<string.h>int n,used[1005];double map[1005][1005],min[1005];void find_short(int s){int i,j,pos;double mm;memset(used,0,sizeof(used));for(i=1;i<=n;i++)min[i]=map[s][i];min[s]=1;used[s]=1;for(i=2;i<=n;i++){pos=0;mm=-1;for(j=1;j<=n;j++){if(!used[j]&&mm<min[j]){pos=j;mm=min[j];}}used[pos]=1;if(mm==-1) break;for(j=1;j<=n;j++)if(!used[j]&&min[pos]*map[pos][j]>min[j])min[j]=min[pos]*map[pos][j];}}int main(){int i,j,m,s,e;while(scanf("%d",&n)!=EOF){for(i=1;i<=n;i++)for(j=1;j<=n;j++)scanf("%lf",&map[i][j]);scanf("%d",&m);while(m--){scanf("%d %d",&s,&e);find_short(s);if(min[e]!=0) printf("%.3lf\n",min[e]);else printf("What a pity!\n");}}return 0;}hdu1358 Minimum Transport Cost 按字典序输出最短路径hdu1385分类:图论2012-07-27 23:2339人阅读评论(0)收藏编辑删除Minimum Transport CostTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 3923 Accepted Submission(s): 989Problem DescriptionThese are N cities in Spring country. Between each pair of cities there may be one transportation track or none. Now there is some cargo that should be delivered from one city to another. The transportation fee consists of two parts:The cost of the transportation on the path between these cities, anda certain tax which will be charged whenever any cargo passing through one city, except for the source and the destination cities.You must write a program to find the route which has the minimum cost.InputFirst is N, number of cities. N = 0 indicates the end of input.The data of path cost, city tax, source and destination cities are given in the input, which is of the form:a11 a12 (1)a21 a22 (2)...............aN1 aN2 ... aNNb1 b2 ... bNc de f...g hwhere aij is the transport cost from city i to city j, aij = -1 indicates there is no direct path between city i and city j. bi represents the tax of passing through city i. And the cargo is to be delivered from city c to city d, city e to city f, ..., and g = h = -1. You must output the sequence of cities passed by and the total cost which is of the form:OutputFrom c to d :Path: c-->c1-->......-->ck-->dTotal cost : ............From e to f :Path: e-->e1-->..........-->ek-->fTotal cost : ......Note: if there are more minimal paths, output the lexically smallest one. Print a blank line after each test case.Sample Input50 3 22 -1 43 0 5 -1 -122 5 0 9 20-1 -1 9 0 44 -1 20 4 05 17 8 3 11 33 52 4-1 -1Sample OutputFrom 1 to 3 :Path: 1-->5-->4-->3Total cost : 21From 3 to 5 :Path: 3-->4-->5Total cost : 16From 2 to 4 :Path: 2-->1-->5-->4Total cost : 17#include<stdio.h>#include<string.h>#define size 1000int val[size],map[size][size],used[size],min[size],n,start[size],end[size],flag,pre[size];char s1[1300],s2[1300];int ok(int n1,int n2,int s)//比较字典序大小{int i,k;i=0;s1[i++]=n1+'0';k=pre[n1];while(k!=s){s1[i++]=k+'0';k=pre[k];}s1[i++]=s+'0';s1[i]='\0';strrev(s1);//把字符串翻转过来i=0;s2[i++]=n1+'0';k=n2;//因为依然是n1(j)为最后一个通过n2(pos)架桥while(k!=s){s2[i++]=k+'0';k=pre[k];}s2[i++]=s+'0';s2[i]='\0';strrev(s2);if(strcmp(s2,s1)<0)return 1;else return 0;}void find_short(int s){int i,j,mm,pos;memset(used,0,sizeof(used));for(i=1;i<=n;i++){min[i]=map[s][i];if(map[s][i]!=999999999) //这一步居然忘记了阿弥陀佛记住这个千万不能少pre[i]=s;}min[s]=0;used[s]=1;for(i=2;i<=n;i++){mm=999999999;for(j=1;j<=n;j++){if(!used[j]&&mm>min[j]){pos=j;mm=min[j];}}if(mm==999999999) break;used[pos]=1;for(j=1;j<=n;j++)if(!used[j]&&min[pos]+map[pos][j]+val[pos]<min[j]){min[j]=min[pos]+map[pos][j]+val[pos];pre[j]=pos;}elseif(!used[j]&&min[pos]+map[pos][j]+val[pos]==min[j])if(ok(j,pos,s)) pre[j]=pos;//如果pos之前的字典序较小那么更新}}void print(int s,int e){int a[size],i,k;k=0;a[k++]=e;i=e;while(s!=i){i=pre[i];a[k++]=i;}printf("Path: ");for(i=k-1;i>0;i--)printf("%d-->",a[i]);printf("%d\n",a[0]);}int main(){int i,j,s,e,num;while(scanf("%d",&n)&&n!=0){num=0;for(i=1;i<=n;i++)for(j=1;j<=n;j++){scanf("%d",&map[i][j]);if(map[i][j]==-1) map[i][j]=999999999;}for(i=1;i<=n;i++)scanf("%d",&val[i]);while(1){scanf("%d %d",&s,&e);if(s==-1&&e==-1) break;start[num]=s;end[num++]=e;}for(i=0;i<num;i++){flag=0;find_short(start[i]);printf("From %d to %d :\n",start[i],end[i]);if(start[i]!=end[i])print(start[i],end[i]);else printf("Path: %d\n",start[i]);printf("Total cost : %d\n",min[end[i]]);printf("\n");}}return 0;}/*记录路径思路就是加入一个pre[]数组时时更新每个点前面的点是什么另外不要忘记从始点出发到i的所有的pre都要赋值初始点本题要求按字典序找出最短的路径一开始我感到很恐惧不知道怎么做其实心里没有必要那么害怕只要尝试着一点一点的去做不要不敢尝试就退却把大问题分解成一个一个小问题硬着头皮也要上(看了别人代码才A了)*/hdu1548 A strange lift 不错的变相最短路考察分类:图论2012-07-27 23:2412人阅读评论(0)收藏编辑删除A strange liftTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 5507 Accepted Submission(s): 2009Problem DescriptionThere is a strange lift.The lift can stop can at every floor as you want, and there is a number Ki(0 <= Ki <= N) on every floor.The lift have just two buttons: up and down.When you at floor i,if you press the button "UP" , you will go up Ki floor,i.e,you will go to the i+Ki th floor,as the same, if you press the button "DOWN" , you will go down Ki floor,i.e,you will go to the i-Ki th floor. Of course, the lift can't go up high than N,and can't go down lower than 1. For example, there is a buliding with 5 floors, and k1 = 3, k2 = 3,k3 = 1,k4 = 2, k5 = 5.Begining from the 1 st floor,you can press the button "UP", and you'll go up to the 4 th floor,and if you press the button "DOWN", the lift can't do it, because it can't go down to the -2 th floor,as you know ,the -2 th floor isn't exist. Here comes the problem: when you is on floor A,and you want to go to floor B,how many times at least he havt to press the button "UP" or "DOWN"?InputThe input consists of several test cases.,Each test case contains two lines.The first line contains three integers N ,A,B( 1 <= N,A,B <= 200) which describe above,Thesecond line consist N integers k1,k2,....kn.A single 0 indicate the end of the input.OutputFor each case of the input output a interger, the least times you have to press the button when you on floor A,and you want to go to floor B.If you can't reach floor B,printf "-1".Sample Input5 1 53 3 1 2 5Sample Output3/*题意是在某一层的楼梯电梯只能上或者下相应的层数从a-》b最少要上下多少次如果不能从a到b则输入-1 变形的最短路问题层数就是点看第几层和第几层有路此题比较简单*/#include<stdio.h>#include<string.h>int map[205][205],used[205],min[205],n,start,end;void init(){int i,j;for(i=1;i<=n;i++)for(j=1;j<=n;j++)if(i!=j) map[i][j]=999999999;else map[0][0]=0;}void find_short(){int i,j,mm,pos;memset(used,0,sizeof(used));for(i=1;i<=n;i++)min[i]=map[start][i];min[start]=0; used[start]=1;for(i=2;i<=n;i++){pos=0;mm=999999999;for(j=1;j<=n;j++){if(!used[j]&&mm>min[j]){pos=j;mm=min[j];}}used[pos]=1;if(mm==999999999) break;for(j=1;j<=n;j++){if(!used[j]&&min[pos]+map[pos][j]<min[j])min[j]=min[pos]+map[pos][j];}}}int main(){int i,d;while(scanf("%d",&n)!=EOF){if(n==0) break;scanf("%d %d",&start,&end);init();for(i=1;i<=n;i++){scanf("%d",&d);if(i-d>=1) map[i][i-d]=1;if(i+d<=n) map[i][i+d]=1;}find_short();if(min[end]==999999999) printf("-1\n");elseprintf("%d\n",min[end]);}return 0;}A Walk Through the ForestTime Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 2963 Accepted Submission(s): 1075Problem DescriptionJimmy experiences a lot of stress at work these days, especially since his accident made working difficult. To relax after a hard day, he likes to walk home. To make things even nicer, his office is on one side of a forest, and his house is on the other. A nice walk through the forest, seeing the birds and chipmunks is quite enjoyable.The forest is beautiful, and Jimmy wants to take a different route everyday. He also wants to get home before dark, so he always takes a path to make progress towards his house. He considers taking a path from A to B to be progress if there exists a route from B to his home that is shorter than any possible route from A. Calculate how many different routes through the forest Jimmy might take.InputInput contains several test cases followed by a line containing 0. Jimmy has numbered each intersection or joining of paths starting with 1. His office is numbered 1, and his house is numbered 2. The first line of each test case gives the number of intersections N, 1 < N ≤ 1000, and the number of paths M. The following M lines each contain a pair of intersections a b and an integer distance 1 ≤ d ≤ 1000000 indicating a path of length d between intersection a and a different intersection b. Jimmy may walk a path any direction he chooses. There is at most one path between any pair of intersections.OutputFor each test case, output a single integer indicating the number of different routes through the forest. You may assume that this number does not exceed 2147483647Sample Input5 61 3 21 4 23 4 31 5 124 2 345 2 247 81 3 11 4 13 7 17 4 17 5 16 7 15 2 16 2 1Sample Output24大致题意:他的办公室用1表示,家用2 表示,从1到2,中间可能会经过其它节点,而该节点可走的原则是:假设他此时在A处,B与其相邻,只有当B到2 路线中存在一条比A到2 的任意一条路径都短的路径,才能走B。

相关文档
最新文档