
ACM算法竞赛入门经典题解
文章平均质量分 82
主要包含数据结构, 图论, 计算几何, 其他(动态规划,数论)等4大块ACM算法题解.主要是笔者自己学习ACM算法过程中做的各类专题算法,题目大多不难,但是有益于理解算法基本的原理以及基础应用,且各类算法专题都有比较多的入门题解分类.为算法能力的进阶打下坚实的基础.
focus_best
这个作者很懒,什么都没留下…
展开
-
ZOJ 3321 Circle(并查集)
ZOJ 3321 Circle(并查集)http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3321题意: 给你一个n节点m条边的无向图,问你该图是否正好是一个环?分析: 无向图是一个简单环 充要条件是 所以节点的度数==2且图连通. 所以我们只需要记录每个节点的度且用原创 2014-09-22 12:20:39 · 1924 阅读 · 2 评论 -
POJ 2253 Frogger(并查集+二分)
POJ 2253 Frogger(并查集+二分)http://poj.org/problem?id=2253题意:给你N个石头的坐标(x,y),现在青蛙要从第一个石头跳到第二个石头上去,但是青蛙每次最大的跳跃距离有限制.所以现在问你青蛙从第一个石头跳到第二个石头的最短跳跃距离是多少?分析: 网上说这题有最短路径解的,生成树解的.本来我是冲着最短路径解法来的,但是看了一遍原创 2014-07-11 18:25:32 · 1549 阅读 · 0 评论 -
HDU 3038 How Many Answers Are Wrong(路径压缩并查集)
HDU3038 How Many Answers AreWrong(路径压缩并查集)分析:本题与POJ1733很相似,也是连续区间的并查集问题.http://blog.youkuaiyun.com/u013480600/article/details/21128299首先本题令v[a]表示半开半闭区间(F[a],a]内序列的和(其中保证F[a]每当读入 u v sum时,令a=u-1,b=v.原创 2014-03-13 13:59:52 · 1148 阅读 · 0 评论 -
POJ 1733 Parity game(路径压缩并查集+离散化)
POJ 1733 Parity game(路径压缩并查集+哈希表)分析:令s[x]表示(F[x],x](如果F[x]>x,则为(x,F[x]] )之间1个数的奇偶性,s[x]=1表奇,s[x]=0表偶.读入u v even(此时u肯定如果a和b在同一个连通分量,那么s[ (a-1,b] ] = s[a]^s[b]如果a和b不在同一个连通分量,那么合并F[a]和F[b],其相对大小无原创 2014-03-12 23:46:06 · 1371 阅读 · 0 评论 -
POJ 2524 Ubiquitous Religions(并查集)
POJ 2524 Ubiquitous Religions(并查集)题目大意:给你n个节点和m条边,然后问你有多少个连通分量.分析:每读入一条边,如果这条边的两个点不在一个连通分量,那么总的连通分量数目就减少1.初始连通分量有n个.AC代码:344ms#include#includeusing namespace std;const int MAXN=50000+100;i原创 2014-03-12 16:10:44 · 1055 阅读 · 0 评论 -
POJ 2492 A Bug's Life(路径压缩并查集)
POJ2492 A Bug's Life(路径压缩并查集)问题描述:有N个虫子和M次两个不同虫子的交流行为.现在假设虫子只有两种性别,且只有不同性别的虫子才会相互相互交流.问你这M次交流行为中是否有一些虫子违法了上述假设?分析:路径压缩并查集,如果两个虫子交互,那么合并他们的连通分量,且v[i]=0表示它和父节点同性别,v[i]=1表示它和父节点不同性别.如果有处于同一个连通分量的虫子交流原创 2014-03-12 12:41:31 · 1101 阅读 · 0 评论 -
POJ 1988 Cube Stacking(路径压缩并查集)
POJ 1988 Cube Stacking(路径压缩并查集)分析:主要就是并查集路径压缩,如果M a b就等于把a所属的连通分量连接到b所属的连通分量上每个节点维护3个变量:其与父节点之间有多少个节点(包括父节点)v,(如果该节点是根节点)还需维护本连通分量一共有多少节点的信息total.由本节点离父节点直接还有多少个节点(初始为0,)可以回答C询问.当进程M操作时候比如M a原创 2014-03-12 10:41:05 · 1206 阅读 · 0 评论 -
POJ 2236 Wireless Network(并查集)
POJ2236 Wireless Network(并查集)分析:每修复一台电脑,就把它并入距离它不差过D距离的连通分量,并和并这些所有的连通分量.每次查询只需要看被查询的两台电脑是否在同一个连通分量即可.现在问题就是如何快速的知道任何一个点附近距离它不超过D的所有其他点?直观方法:用两个for来遍历每一个点,求他们之间的距离.用vector保存每个点附近距离不超过D距离的顶点编号.(点原创 2014-03-12 10:35:49 · 1434 阅读 · 0 评论 -
POJ 1984 Navigation Nightmare(路径压缩并查集)
POJ 1984 Navigation Nightmare(路径压缩并查集)分析:定最左上角的坐标为(0,0).x为横坐标,y为纵坐标.首先本题需要离线处理,即先读入所有的输入数据,然后根据询问的时间点来处理.其次,本题可用并查集,且x[]和y[]数组保存了当前点到其父节点的坐标差值.比如第一句输入为 1 2 3 N 表示从1点朝北方向长3的路可以到2点,那么2的父亲就是1点,且x[2原创 2014-03-11 23:13:04 · 1410 阅读 · 0 评论 -
POJ 1703 Find them, Catch them(路径压缩并查集)
POJ 1703 Find them, Catchthem(路径压缩并查集)一个城市由N个坏人,他们分别属于两个帮派.且这两个帮派里面最少都有1个人.现在给出如下两种语句:D a b 表示a和b肯定不在一个帮派A a b 你需要回答a和b的关系.输入:首先是一个T (1 输出:回答每条A语句.分析:带路径压缩的并查集:a与其父亲同帮派:v[a]=0a与其父亲不同帮派原创 2014-03-11 20:13:54 · 1249 阅读 · 0 评论 -
POJ 1611 The Suspects(并查集)
POJ1611The Suspects(并查集)现在有n个学生(从0号到n-1号),其中0号学生是有可能非典的,只要和被怀疑有非典的学生在一个社团的学生都是有可能有非典的且需要被隔离,但是学校有很多社团,所以现在要你求一共有多少学生需要被隔离?输入:多组实例.每个实例第一行n和m (0 输出:需要被隔离的学生数.分析:所有学生被处理前都是独立的连通分量,以自己作为根.只要读入一个社原创 2014-03-11 11:17:28 · 1500 阅读 · 0 评论 -
HDU 1325 POJ 1308 Is It ATree?(并查集)
HDU 1325 POJ 1308 Is It ATree?(计算树的入度)一棵树是一个数据结构,它要么是一个空要么是满足下面特性的结构:1. 只有一个根节点,这儿根节点没有入度.2. 除了这个根节点其他所有的节点都只有一个入边(指向它的边).3. 从根节点到任意其他的节点有且仅有一条路现在给你一颗树的所有有向边,然后问你这个树是不是一颗合法的树.输入:多原创 2014-03-11 00:54:42 · 1295 阅读 · 0 评论 -
HDU 3635 Dragon Balls(并查集:路径压缩)
HDU3635Dragon Balls这里有N个龙珠,每个龙珠初始时都在本身的城市(第i个龙珠在第i个城市),然后要你回答对应的询问。输入:首先是一个T(0T A B(1Q A。你需要输出X,Y,Z。X是A龙珠目前所在的城市,Y是X城市所有的龙珠,Z是A龙珠被转移的次数。输出:回答每条Q命令的X,Y,Z.分析:其实这就是一个并查集的应用,龙珠被转移的次数就是该龙珠距离根节点原创 2014-03-09 17:04:31 · 1487 阅读 · 0 评论 -
HDU 1272 小希的迷宫(并查集:判断连通且结构为树)
HDU 1272 小希的迷宫上次Gardon的迷宫城堡小希玩了很久(见Problem B),现在她也想设计一个迷宫让Gardon来走。但是她设计迷宫的思路不一样,首先她认为所有的通道都应该是双向连通的,就是说如果有一个通道连通了房间A和B,那么既可以通过它从房间A走到房间B,也可以通过它从房间B走到房间A,为了提高难度,小希希望任意两个房间有且仅有一条路径可以相通(除非走了回头路)。小希现在把原创 2014-03-09 13:32:37 · 1386 阅读 · 0 评论 -
HDU 1232 畅通工程(并查集)
HDU 1232 畅通工程Time Limit: 4000/2000 MS(Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 25811 Accepted Submission(s): 13493Problem Description某省调查城镇交通状况,得到现有城镇道路原创 2014-03-09 11:35:43 · 954 阅读 · 0 评论 -
HDU 1213 How Many Tables(并查集)
HDU1213 How Many Tables现在给你由1到N个数字组成的M对整数对,问你有多少个连通分量。每对整数X和Y(X不等于Y)表示X和Y在一个连通分量里面。输入:首先是T(1输出:连通分量个数。分析:直接读取数据,判断即可。AC代码:0ms #include#include#includeusing namespace std;const int MAXN原创 2014-03-09 11:16:59 · 1111 阅读 · 0 评论 -
UVA 1329 Corporative Network(并查集:路径压缩)
UVA1329 Corporative Network初始时有n个点,每个点都没有父节点,然后依次执行下面两条命令:I u v :把节点u的父亲设置为v,并且设u节点到v的距离为|u-v|%1000,输入保证执行I命令的时候,u没有父节点。E u:查询u节点到根节点的距离。输入:首先是T,表示实例个数。每个实例第一行是n(5输出:对于每条E指令,输出查询结果。分析:对于每条原创 2014-03-09 00:19:33 · 1222 阅读 · 0 评论 -
UVA 1160 X-Plosives(并查集)
UVA 1160 X-Plosives现在手上有一些化合物,每个化合物都不同且由两个整数构成,当你手上存在这种情况时:手上有至少N(N>2)个化合物且其中有N个化合物正好包含N个不同的整数(即这N个整数每个出现了2次)。那么此时化合物不稳定。比如你有化合物1和2,2和3,3和1那么就是不稳定的,但是你有1和2,2和3 那么就是稳定的。现在给出所有化合物给你的顺序,你要保证不会出现化合物原创 2014-03-08 23:39:17 · 1306 阅读 · 0 评论 -
HDU 1198 Farm Irrigation(并查集)
HDU 1198 Farm Irrigation题目大意,给你一个N*M的矩阵,有11种格子,每个格子互联的部分不同,问你矩阵一共有几个连通分量。输入:每个实例第一行是N和M,1 输出:连通分量个数。分析:从上到下,从左到右一个一个格子分析,如果当前格子连通上方且它上面已经有格子(且该格子也连通了当前格子),那么它属于上面那个连通分量,如果当前格子连通左边,且它左边还有格子(且该格原创 2014-03-08 21:33:25 · 1265 阅读 · 0 评论 -
HDU 4496 D-CITY(并查集)
HDU4496 D-CITY(并查集)题目描述:给出一个有N(0输入:第一行是N和M,然后是M行数(X,Y)(0输出:依次输出所求的连通分量数。分析:当删除前K条边时图所剩的连通分量数就是N个孤立的点只添加后M-K跳边时,所具有的连通分量数。所以仅需倒叙插入每条边,分别保存插入边后有的连通分量数在数组内,然后输出数组即可。AC代码中未加while(scanf("%d%d",原创 2014-01-14 22:53:06 · 1404 阅读 · 0 评论 -
UVA 11992 Fast MatrixOperations(线段树)
UVA 11992 Fast MatrixOperations(线段树)http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=18697分析:详解见刘汝佳 训练指南P207 可以看到题目中的矩阵最多20行,但是却最多有100W元素,所以可以想到对于矩阵每行维护一棵线段树就行. 线段树维护的信息:有原创 2014-04-01 13:04:43 · 1212 阅读 · 0 评论 -
HDU 1542 Atlantis(线段树:扫描线)
HDU1542 Atlantis(线段树:扫描线)题意:二维平面有n个平行于坐标轴的矩形,现在要求出这些矩形的总面积. 重叠部分只能算一次.分析: 首先假设有下图两个矩阵,我们如果用扫描线的方法如何计算它们的总面积呢?首先我们将矩形的上下边分为上位边(即y坐标大的那条平行于x轴的边),和下位边(y坐标小的平行于x轴的边).然后我们把所有矩形的上下位边按照他们y坐标原创 2014-03-30 01:46:38 · 9623 阅读 · 14 评论 -
HDU1540 Tunnel Warfare(线段树:维护最大连续子串)
HDU1540 Tunnel Warfare(线段树:区间合并)http://acm.hdu.edu.cn/showproblem.php?pid=1540分析: 首先先来分析题目中的3种操作:1.D x: 该操作就是单点更新2.Q x: 该操作可以分解为查区间[1,x]的最大连续0后缀长L和区间[x,n]的最大连续0前缀长R,则R+L-1即为所求.有关前缀查询和后原创 2014-03-29 19:18:43 · 1772 阅读 · 1 评论 -
HDU 2871 Memory Control(线段树:区间合并)
HDU 2871 Memory Control(线段树:区间合并)http://acm.hdu.edu.cn/showproblem.php?pid=2871分析: 首先分析题目中能进行的几种操作:1. Reset: 所有内存单元置02. New x:申请一块包含连续x个单元的空闲内存块3. Freex: 释放包含x号单元的(已被占用)内存块原创 2014-03-29 16:43:31 · 1076 阅读 · 0 评论 -
HDU 3308 LCIS(线段树:单点更新,求最大连续子串)
HDU 3308 LCIS(线段树:单点更新,区间合并)分析: 首先题目中找的递增序列是严格增加的,如果有7,7这样的序列不算递增.其次本题是单点更新,所以不用PushDown,只用PushUp就行. 线段树维护信息:val(表节点的值,只有子节点有用,这个信息也可以不维护的),sub(最长上升子序列的长度),pre(最长上升前缀的长度),suf(最长上升后缀的长原创 2014-03-28 18:58:10 · 2509 阅读 · 0 评论 -
HDU 3397 Sequence operation(线段树:成段更新,查询连续目标子串长度)
HDU 3397 Sequence operation(线段树:成段更新,区间合并)分析:注意在总的query地方可以不用编写查询前缀和后缀的函数,特别注意优化二的地方. 1.本题有点类似于POJ3225:http://blog.youkuaiyun.com/u013480600/article/details/22284341也是同时有cover操作和异或操作,但是这里用异或标记原创 2014-03-28 22:29:58 · 1099 阅读 · 0 评论 -
POJ 3667 Hotel(线段树:区间覆盖,维护最大连续子区间)
POJ 3667 Hotel(线段树:区间合并)分析: 首先本题类似于UVA1400 ,所有区间合并类的线段树基本都需要维护3类信息:最大区间,最大前缀,最大后缀. 维护一棵线段树,该线段树每个节点维护信息:在该节点所代表的区间内的覆盖情况cover: 为0时表示没有被覆盖,为1时表示被覆盖了,为-1时表示子节点中既有被覆盖的也有没被覆盖的.最长连续区间长度原创 2014-03-28 16:46:52 · 2143 阅读 · 0 评论 -
POJ 2991 Crane(线段树:维护向量+计算几何)
POJ 2991 Crane(向量旋转+线段树_成段更新)分析: 首先一个向量(x,y)逆时针绕起点旋转rad度后得到的向量为:newx = x*cos(rad)-y*sin(rad) newy = x*sin(rad)+y*cos(rad)然后我们要知道另外一个事实:如果一条折线由多个向量构成,那么这条折线段的终点坐标一定为起点+向量1+向量2+..+向量n的结果原创 2014-03-28 02:13:00 · 1667 阅读 · 1 评论 -
POJ 2777 Count Color(线段树:区间覆盖)
POJ 2777 Count Color(线段树:成段更新)分析:本题是POJ 1436的弱化版本:http://blog.youkuaiyun.com/u013480600/article/details/22313189 首先本题的区间是一个一个的整数,所以不用乘2考虑开区间闭区间的问题了.所以这里的线段树维护一个color信息,其中color>0表示节点所指的区间都有某种颜色原创 2014-03-27 22:14:07 · 1410 阅读 · 1 评论 -
POJ 1436 Horizontally VisibleSegments(线段树:区间覆盖染色)
POJ 1436 Horizontally VisibleSegments(线段树:成段更新+区间开闭)分析:1. 首先读入所有的线段,然后按x轴坐标从小到大排序,然后我们一次处理每条线段,用一个二维矩阵mark[i][j]保存第i条线段和第j条线段之间的关系.(如果相互可以看到,则mark为true,否则为false). 2. 下面的问题是如果求出任意两线段之间的可见原创 2014-03-27 19:26:25 · 1534 阅读 · 1 评论 -
POJ 3225 Help with Intervals(线段树:区间置0/1,区间异或)
POJ3225 Help with Intervals(线段树:成段更新,开闭区间)分析:找到几个小BUG,直接AC了,还是需要写出自己的所有思路,才比较好写代码. 首先这道题目要处理区间,所以我们在线段树的各个节点用0表示不包括,1表示包括,-1表示子节点中既有包括又有不包括.下面分析对应的5种操作,假设T表示的区间是[l,r]:U T: [l,r]区间置1I T: [0,l原创 2014-03-27 13:57:00 · 3608 阅读 · 0 评论 -
UVA 1400 "Ray, Pass methe dishes!"(线段树,区间合并)
UVA 1400 "Ray, Pass methe dishes!"(线段树,区间合并)分析: 本题比较复杂,详解见:刘汝佳训练指南P201 建立一棵线段树,每个节点维护下面3种信息max_sub,max_prefix和max_suffix,分别表示最大连续和,并保存相应的坐标信息x[],y[],p[],s[].然后对于一个查询[20,50]区间的最大连续和,由原创 2014-03-26 23:33:01 · 1399 阅读 · 0 评论 -
HDU 1698 Just a Hook(线段树:区间set,区间查询)
HDU 1698 Just a Hook(线段树:区间set,区间查询)分析:线段树区间set基本操作,详情看刘汝佳训练指南。//HDU 1698 线段树 区间set 区间查询#include#include#includeusing namespace std;#define lson i*2,l,m#define rson i*2+1,m+1,rconst int MA原创 2014-03-26 19:18:05 · 1283 阅读 · 0 评论 -
POJ 3468 A Simple Problemwith Integers(线段树:区间add,区间查询)
POJ 3468 A Simple Problemwith Integers(线段树:区间add,区间查询)分析:基本题型。熟练代码模板。AC代码:1797ms//POJ 3468 区间add,区间查询#include#include#includeusing namespace std;//每当有add加到i节点上,直接更新i节点的sum.//也就是说如果要查询区间[1原创 2014-03-26 19:16:58 · 1226 阅读 · 0 评论 -
POJ 2528 Mayor's posters(离散化+区间set线段树)
POJ 2528 Mayor's posters(离散化+区间set线段树)分析: 首先题目的区间范围高达1000W,如果直接计算可能超内存且超时间。所以需要离散化。 离散化一:比如对于如下区间集合,[1,1000],[500,2000],[1500,2500].那么把所有区间端点1,500,1000,1500,2000,2500离散化后就是1,2,3,4,5,原创 2014-03-26 19:14:56 · 1199 阅读 · 2 评论 -
POJ 2886 Who Gets the MostCandies?(线段树+模拟+求数的约数个数)
POJ 2886 Who Gets the MostCandies?(线段树+模拟+求数的约数个数)分析: 首先建立一棵线段树,其每个叶节点都是1(代表每个孩子都在圈中,如果第i个孩子不在圈中,那么就令第i个叶子(不一定编号为i)sum=0)。分析题中的例子:4 2Tom 2Jack 4Mary -1Sam 1 假设我们第一个出去的孩子是原创 2014-03-26 00:02:04 · 1177 阅读 · 0 评论 -
POJ 2828 Buy Tickets(线段树:查找并更新从左到右第i个1)
POJ 2828 Buy Tickets(线段树,逆推)分析: 本题的解法类似于POJ 2182:http://blog.youkuaiyun.com/u013480600/article/details/21574467 首先对于这种一个一个元素插入队列的例子,我们可以用链表来实现,插入时间为O(1),但是每次找到正确的插入位置pos,需要的时间是O(n),那么如何快原创 2014-03-25 19:38:14 · 1232 阅读 · 0 评论 -
HDU 2795 Billboard(线段树:找到线段树中>=给定值的第一个元素位置 并 更新该点)
HDU 2795 Billboard(线段树:单点更新,区间查询)分析: 首先由于有n(n 注意: 如果h比n小,那么线段树的节点总数定为h个,否则定位n个.如果wi>w,那么直接输出-1. 现在我们依次读入wi,找到能放下wi的序号最小的线段树叶节点,然后更新线段树即可. 其中线段树中节点维护的信息是:本节点控制的区间[L,R原创 2014-03-25 11:55:15 · 1419 阅读 · 0 评论 -
HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)
HDU 1394 Minimum Inversion Number(线段树:单点更新,区间求和)分析: 首先对于读入的每个a[i],执行a[i]++操作.使得序列变成1到n之间.首先利用线段树求出初始序列a1,a2…an的逆序数ans.类似于树状数组对逆序的求法.详解:http://blog.youkuaiyun.com/u013480600/article/details/21原创 2014-03-25 00:29:41 · 1068 阅读 · 0 评论 -
HDU 1754 I Hate It(线段树:单点替换,区间最值)
HDU 1754 I Hate It(线段树:单点替换,区间最值)分析:依然是线段树的基本操作.详解:http://www.notonlysuccess.com/index.php/segment-tree-complete/AC代码: 515ms//HDU1754#include#include#includeusing namespace std;const原创 2014-03-24 23:42:06 · 1234 阅读 · 0 评论