自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

AC_Arthur的专栏

Always challenge miracles!

  • 博客(62)
  • 收藏
  • 关注

原创 HDU 5119 Happy Matt Friends(DP)

求解方案数的简单DP,比赛时没有往DP上想,思维比较局限。状态转移很好写,类似于背包,我用记忆化搜索写的容易写,但是效率比较低,还占内存,读者可以改成递推式,还可以改成滚动数组,因为每一层的状态只用到它上一层的状态 。细节参见代码:#include#include#include#include#include#include#include#include#inclu

2015-08-31 21:36:43 854

原创 HDU 1565 方格取数(1)(最大独立点权覆盖 | 最小割)

该题是一道经典的求最大点权独立集问题的题目 。  关于定义我就不多说了 。 说一下几个重要的关系 :1.最大流 = 最小割 = 最小点权覆盖集 = sum - 最大点权独立集 。因此,该题其实还可以用最小割来做,思想是相同的 。 因为我们不能取相邻的数字,所以很容易联想到最小割  。那么我们可以先给每个格子编号1或2,形成二分图。 然后由1到2连边 。容量INF,与源点和汇点相连的

2015-08-31 10:24:35 989 1

原创 HDU 3572 Task Schedule(最大流Dinic算法)

该题非常经典,建图的方法非常巧妙,因为每个任务的完成不一定要连续,而且可以换机器完成,而且我们注意到时间点最多500,很小,所以我们将时间点抽出来建图。对于每个任务,将其时间范围内的点与之连起来,容量显然为1 ,并与汇点相连,容量为p[i] 。  对于每个时间点,因为最多可以有m台机器同时工作,所以容量为m 。一开始老想着任务和机器之间怎么建立联系了。细节参见代码:#include

2015-08-30 20:54:06 1332

原创 HDU 2732 Leapin' Lizards(拆点法+最大流)

该题是一道比较简单拆点+最大流的题目,因为每个柱子都有一定的寿命,很容易将其对应成流量,那么处理结点容量的一般方法当然是拆点法 。该题反而对边的容量没有要求,为保险起见可以设成无穷大。   该题的思路很好想,建议独立编写代码 。推荐题目: 点击打开链接    结点法的一些见解 也可以看这里。细节参见代码:#includeusing namespace std;typedef lon

2015-08-30 17:13:39 1340

原创 HDU 1165 Eddy's research II(递推)

坑了我好久,乍看很简单,记忆化搜索结果爆栈,然后改成递推之后WA 。 后来发现,是在计算m=3的数据时出现了错误,因为当m=3时,即使n很小,结果也会很大,所以无法利用m=2时的结果递推,要怎么办呢?  将m=2的结果打印出来可以发现这是一个等差数列,通项为S(n) = 2*n + 3;这有什么用呢? 我们可以发现,当 m=3时由递推式可以写成A(m,n) = A(2,A(m,n-1)) =

2015-08-30 10:52:38 867

原创 HDU 1978 How many ways (DP)

一个比较简单的DP,希望读者在看题解之前

2015-08-30 09:02:57 1188 1

原创 HDU 2851 Lode Runner(简单DP)

比较简单的一道DP题,题意是给你n条路,每条路的最右边有一个梯子,也就是说只要一条路的最右边在另一条路上,那么就可以从这条路去那条路。一开始没考虑清楚状态怎么表示,TLE了一次。 因为路的最右边从小到大排序,且不能向回走,所以用d[i]表示到大i点的最优解,那么当前这个状态只能由该点之前的某条路也就是某个状态转移过来,所以只要枚举i点之前的所有路就行了,另外注意一下边界。细节参见代码:

2015-08-29 09:24:14 1396

原创 12549 - Sentry Robots (二分图匹配)

该题和HDU 5093 如出一辙 传送门  。即求解二分图最大匹配数 = 最小点集覆盖 。 该题要求用尽量少的机器人看守所有重要的点,并且障碍物会阻隔机器人的看守范围  。我们不妨将行列分开,按照行和列的最大看守范围编号,这样得到的就是最大匹配数 。 由于要求看守所有重要的点,所以这样可以有效去重,进行了最大匹配之后还可以保证一定看守了所有的点 。 建好图之后套Dinic模板就行了 。该题

2015-08-27 09:23:08 1466

原创 HDU 5093 Battle ships(二分图匹配)

该题是一道经典的二分图匹配题目 。  同一列(行)上不能放两个船除非有冰山隔着。对于这种二维平面图,我们很容易想到将行和列分成两个集合,进行二分图匹配,当一个行坐标匹配到一个列坐标时,该格子可以放置船。那么为了使任意两个船都不在同一行或者同一列,除非有冰山,我们可以将每一行中一块连续的只能放置一个船的区域都设成一个编号,同样的按照列也这样处理,这样就相当于将行和列缩点了,接下来用最大流模板套一套就

2015-08-27 08:44:27 1590

原创 HDU 4687 Boke and Tsukkomi(一般图匹配|带花树)

比赛的时候刚开始看这题还以为是二分图匹配,后来才发现根本不是,因为该题存在长度为奇数的圈 。  比如1->2,2->3,3->1 。 所以该题要用一般图匹配,即带花树算法 。比赛时抄的模板有地方抄错了,上述样例出现了死循环 。   赛后补题的时候用map去重却得不到正确答案,不知为何,暂放 ,下面给出一种正确解法。 细节参见代码:#include#include#include#

2015-08-26 20:52:46 1046

原创 HDU 4268 Alice and Bob(贪心+STL)

该题一开始我用multiset写了一发,写的比较裸,TLE了 。 后来队友想到了一个比较好的方法 :将两个结构体排序之后,从大到小枚举Alice的h,对于每个h,将Bob中满足h小于当前h的牌的w加进multiset,然后用二分函数查找一下大于等于当前w的第一个数,当前迭代器的上一个指针就是小于当前w的最大w,找到就删除。那么也就是我们用了这样的贪心策略:对于Alice的每一张牌,要覆盖一张Bob

2015-08-25 19:42:36 930 1

原创 10288 - Coupons (数学期望)

没什么好说的了,看代码吧:#includeusing namespace std;typedef unsigned long long ll;int n,m;ll gcd(ll a,ll b) { return b == 0 ? a : gcd(b,a%b);}int gainLen(ll a) { int cnt = 0; while(a > 0) {

2015-08-25 09:58:04 845

原创 HDU 4786 Fibonacci Tree(最小生成树)

该题其实就是最小生成树的变形,先求一个最小生成树的权值,再求一个最大生成树的权值,显然在这两个权值之间的所有值都可以取到(你总可以拿一条黑边换成一条白边)。那么我们只要看一下这些值中有没有斐波那契数就行了。小于100000的斐波那契数只有几十个,直接枚举就行了 。 细节参见代码:#include#includeusing namespace std;typedef long long

2015-08-25 09:23:43 992

原创 UVA 1664 - Conquer a New Region(并查集)

该题巧妙的运用了并查集,运用了类似于最小生成树算法的过程 ,通过该题可以对并查集有一个更深的理解 。 由于i和j唯一通路上容量的最小值为该两点的容量,求一个点到其他所有点的容量最大值 。首先,解决两点的容量问题 ,我们将所有边从大到小排序,然后从大到小枚举,我们假设根结点就是要找的城市中心点,那么当又加入一条边时,该边的两个顶点所在的集合设为A、B,集合A、B的顶点a、b,要让谁当中心点呢

2015-08-24 21:13:21 1470

原创 1660 - Cable TV Network(最大流最小割)

该题又是一道经典的最小割问题,不过不是割边而是割点 。问题是:最少删除几个点可以让图不连通 。 我们都知道最大流对应着最小割,所以重点在于建模 。为了形成割,那么必须让点具有“流量”的性质,怎么做呢? 对,拆点 。 和例题1658类似的方法,我们将每个点拆成两个点,连一条容量为1的边,那么每个点就被赋予了流量的性质,这次我们反而要令边的容量为无穷大,因为要删除点而不是边 。 另外因为我们不

2015-08-24 10:31:19 1591

原创 UVA 10801 - Lift Hopping (Dijkstra算法/最短路)

比较简单的最短路问题,唯一的不同是更换电梯的时候需要多加60s等待时间,而且第一次上电梯不需要等待60s 。注意到这些细节之后在结构体中多保存一个电梯的id,这样在松弛操作的时候分情况讨论一下就行了 。细节参见代码:#includeusing namespace std;const double INF = 1000000000;const int maxn = 505;int n

2015-08-23 21:38:04 908

原创 820 - Internet Bandwidth(最大流模板题)

最大流裸题,紫书上的图有问题,差点坑到我。。给出Dinic算法模板,比较高效的最大流算法,复杂度为O(v^2*E),而实际上Dinic算法比这个理论界要好得多。 紫书上的Edmonds-Karp算法的复杂度是O(v*E^2),对于边较多的题目来说显然不够高效。细节参见代码:#includeusing namespace std;typedef long long ll;const

2015-08-23 19:57:14 1056

原创 1515 - Pool construction(最大流最小割模型)

该题是一道经典的最小割题目 。  最近学习图论以来一直不是很明白最小割是什么,通过该题,有了一定的认识 。首先我们要知道最大流最小割定理 :对于任意一个只有一个源和一个汇的图来说,从源到汇的最大流等于最小割 。也就是说,对于一个图中的两个集合AB,通过删除一些边让他们恰好不连通,那么删掉的这些边就叫做他们的割了 。  那么最小割和网络流有什么关系呢? 为什么最小割定理是对的呢? 其实很简单

2015-08-23 17:10:08 1394

原创 12661 - Funny Car Racing (最短路)

一道比较基础的最短路问题,和普通最短路的不同之处在于每条道路会开启a时间,关闭b时间的循环  。那么只需要在dijkstra算法中利用d[u]稍微改动一下就行了 。两种情况:1 可以直接通过该条道路 。 2 需要等一会才能通过 。  当然还有可能无论如何都不能通过 。 细节参见代码:#includeusing namespace std;typedef long long ll;

2015-08-23 09:21:55 1806 1

原创 1349 - Optimal Bus Route Design(二分图最小权完美匹配)

该题是一道典型的二分图最小权完美匹配问题 。每个点恰好属于一个有向圈,意味着每个点都有一个唯一的后继 。某个东西恰好有唯一的.....这便是二分图匹配的特点 。将每个结点拆成Xi和Yi,则原图中的有向边u->v对应二分图中的边Xu->Yv 。当流量满载时存在,存在完美匹配,否则不存在 。 网络流这类题目的难点在于将实际问题转化成理论模型,即建图过程 。 要想看出是二分图题目,就要明白这类题

2015-08-22 21:42:40 1858

原创 UVA 1658 - Admiral (拆点+最小费用流)

该题中的拆点法是解决几点容量的通用方法 。  因为只有容量限制的话仍然不能满足每个结点只访问一次这个限制 ,原因很简单,大家画个图就知道了,假设从起点有两条路到同一个结点2,然后又都到末点n,虽然它们满足流量限制但是经过了同一个结点。 那么怎么解决这个问题呢? 答案是:拆点法 。将一个结点拆成两个结点,由真结点连一条容量为1费用为0的边到假结点,这样之后当我们加边的时候,另起始结点为假结点

2015-08-21 20:53:55 2053 1

原创 HDU-1533 Going Home(二分图匹配)

最近开始做最小费用流的题目,该题是二分图完美匹配下的最小权匹配,所谓完美匹配就是说从源点流入的总流量等于从汇点流出的总流量,在这种状态下的最小费用 。 那么显然是要套用最小费用流模板,另外二分图匹配的第一步就是要划分集合,划分两个集合,集合A与源点相连,集合B与汇点相连,至于容量和权值就要依据题目而定 。比如该题,因为每个小人恰好能对应一个房子,所以每个小人与汇点的容量为1,房子与汇点的容

2015-08-21 10:32:31 881

原创 11082 - Matrix Decompressing (网络流建模|二分图匹配)

该题是一道经典的二分图匹配的题目 。现在终于有点明白什么是二分图匹配了,其实说白了就是依赖于最大流算法之上的一种解决特定问题的算法 。 所谓二分图,就是我们假定有两个集合A和B,每个集合中有若干元素(点),其中源点与A相连,汇点与B相连,并且他们的总容量决定了最终答案的上限,所以一定要维护好 。 然后由A中的点向B中的点连线,他们之间也有一定的容量制约关系(具体看题目中的边权值限制)。这样就可以求

2015-08-20 21:06:36 1109

原创 753 - A Plug for UNIX (最大流或二分图匹配)

紫书上网络流部分的第一道例题,  刚刚学了最大流,还没有理解二分图匹配 , 这里就只说一下我用最大流是怎么做的吧 。我们可以假想一个源点,一个汇点,然后对于每一个设备的插头,从源点连一条线,对于每个插座,连一条线到汇点,且容量都为1 。

2015-08-20 18:47:03 955

原创 HDU 1532 Drainage Ditches(基础最大流)

最近开始学习图论,到了网络流部分 。该部分比较难,难度在于有点看不懂, 不过这没有关系,慢慢看,先刷几道水题,将模板中需要注意的地方考虑好   。   之后再刷紫书提高 。 逐步加深对网络流的理解 。 该题非常简单,套上模板就过了 。我第一次写最大流模板,理解的还不深刻,下面的注释是我对代码的理解。细节参见代码:#include#include#include#inclu

2015-08-19 21:26:56 1065

原创 HDU-4081 Qin Shi Huang's National Road System(最小生成树)

今天比赛AC的一道最小生成树的题目 , 学到了不少东西 。 最小生成树的模板很简单,最简洁好写的还是lrj紫书上的代码 。利用并查集加速算法 。该题的不同之处在于它选择任意一条路修成“魔法”道路 , 然后其他路的权值之和还要是最小的一棵次小生成树,并且求魔法道路两端点值之和除以其他路径长之和的最大值 。显然该题的难点在于枚举两个端点之后怎么快速的求出次小生成树权值之和 。  枚举两个端

2015-08-19 19:49:47 978

原创 1262 - Password (暴力枚举)

该题应该是用数学的组合知识做,不过因为密码格子很小,暴力枚举很快而且不容易做错 。需要注意一点,因为每一列中可能有重复的字母,所以会出现重复的密码,因此要在dfs之前排序去重。细节参见代码:#includeusing namespace std;int T,k,n,m,cnt;char s1[10][10],s2[10][10],ans[10],len[10],a1[10][10

2015-08-19 09:42:03 826

原创 1637 - Double Patience (概率DP)

一道状态较多的概率DP,想要表示所有的状态显然要拓展几个维度表示九堆牌当前的状态 。但是这么写太复杂,所以我们不妨用一个vector来储存状态,将dp数组用一个map来表示,即 map ,double> d; 利用vector可以作为函数参数传递这个优点,将大大节省代码量 。概率很好求,在每一次迭代中,寻找所有可以转移的状态数tot,那么状态转移就是d[i] = sum(d[i-1])/t

2015-08-18 21:49:28 972

原创 1638 - Pole Arrangement (递推)

该题用到了DP的思想,递推出所有可能情况 。要想维护所有状态,求出要求的情况,那么显然要维护三个量:几根杆子(DP的序)、从左边看杆子的数量、从右边看杆子的数量 。所以状态表示也要增加相应的维度,用d[i][j][k]表示前i根杆子,从左边看有j根,从右边看有k根的可能情况 。接下来就要想好如何转移状态了 : 当前状态肯定要依赖于上一阶段的状态,那么我们不妨想:当前状态与上一状态的不同

2015-08-18 19:32:23 861

原创 1001 - Say Cheese (Dijkstra算法)

该题是求两点间的最短路问题,用Dijkstra算法比较快 ,跑了0.003s 。方法很简单,将圆看成结点,直接判断两个圆是否相交,如果相交距离为0,否则距离为圆心间距离减去两圆半径。 起点和终点也可以看成是一个半径为0的圆 。这样就变成了两点间的最短路问题,适合用Dijkstra算法求解。  比较坑的是该题说了数据范围n最大100,但是我开了105竟然RE ,看成505就过了 。  所以在

2015-08-18 12:58:09 839

原创 821 - Page Hopping (Floyd)

很裸的Floyd水题,只需要注意一点: 题目中给的结点编号并不是完整的从1~n,不过没有关系,因为我们初始化为INF,当两点间距离不等于INF时相加就可以了。细节参见代码:#includeusing namespace std;const int maxn = 105;const int INF = 1000000;int a,b,n,d[maxn][maxn],kase = 0

2015-08-18 09:51:19 895

原创 658 - It's not a Bug, it's a Feature! (Dijkstra算法)

今天第一次系统的学习了一下最短路算法,开始刷第十一章,第一次写Dijkstra算法,出现了很多喜闻乐见的错误。。而且uva上样例很水,瓢虫也很水 ,坑了我好久。首先是对于结点的处理,我们必须要维护一个二元组,一个表示结点一个表示当前结点最短路。   因为Dijkstra算法利用了优先队列来加速算法,所以需要定义小于运算符,一开始我直接将状态装进了优先队列,显然是不对的,因为优先队列的作用就是取

2015-08-17 21:53:13 852

原创 10048 - Audiophobia (Floyd)

该题是Floyd算法的一个巧妙变形,虽然AC率很高,但是真正要灵活变化到做出该题,显然要明白Floyd算法的思想和原理 ,弄清楚为什么可以这样更改算法的核心部分。Floyd算法其实利用了动态规划的思想,适合求解几点不是很多的稠密图 。   我们都知道,动态规划在利用循环嵌套求解时是要规定一个次序的,这样才能将状态成功的转移 。该题的次序就是由k来定义的,从小到大枚举k,定义其意义为i和j之

2015-08-17 10:53:37 865

原创 247 - Calling Circles (Floyd 求传递闭包)

该题恰好用到刚刚讲到的Floyd求传递闭包 , 因为该题的数据量不是很大, 要是大了估计就要用其他方法了 。  但是这毕竟是一个很简单易写的算法 。求出传递闭包之后就用并查集将在一个电话圈的人合并在一起,最后输出 。 细节参见代码:#includeusing namespace std;int n,m,d[30][30],par[30],kase = 0;string s1,s2

2015-08-17 09:24:52 1292

原创 1151 - Buy or Build (最小生成树)

一道很好的最小生成树题目 。 看似非常复杂,其实仔细分析一下算法的复杂度就会发现,如果加入了lrj说的优化,其实复杂度不高 。就像紫书中说的, 除去购买套餐中的点,剩下的最小边仍然在原始的最小生成树中 。  所以我们用二进制枚举子集的方法枚举所有购买套餐的组合,然后将套餐中的点加入并查集中,再用原始最小生成树中的边补全当前生成树 。二进制枚举子集的复杂度是2^8 。 补全生成树的复杂度是O

2015-08-16 20:56:01 1024

原创 1395 - Slim Span (最小生成树)

UVA上的题就是让人眼前一亮,不同于那些赤裸裸的生成树水题,该题稍加了变化,不是求最小生成树,而是求最苗条生成树 。  因为生成树有很多,而且每一棵生成树的最大边与最小边只差也是不确定的 。所以只能枚举所有的生成树 。套用最小生成树模板 ,我们可以枚举生成树的起点位置,然后向后推终点位置,当n个点全部连通时,那么这棵生成树的边集就是[L,R] 。因为边事先都排好序了, 那么该树的苗条值就是

2015-08-16 19:17:43 824

原创 12219 - Common Subexpression Elimination(表达式树)

草草刷了一下暴力,开始转战图论了。   这是第一道例题,讲解了一种实用而神奇的树状结构:表达式树 。虽然打比赛从来没见过,但是我练这个本来也不只是为了比赛 , 重要的是ACM本身带给我的乐趣 。该题的一个很巧妙的做法是将每一个结点用一个三元组来表示,然后映射到map中以去重 。 其中三元组中有一个string , 我们可以用hash来处理这个string 。因为string最大长度为4,

2015-08-16 17:08:52 1951

原创 hdu-5023 A Corrupt Mayor's Performance Art (线段树区间修改)

今天集训队打比赛的一道题,很明显是个线段树,我们队照着lrj蓝书敲了一通,机智的将修改值和加和改成了位运算:|= 但是好像哪里出了点小问题,就是不对,赛后又水了一遍,竟然过了。。。发现还是lrj的书好啊,市面上的模板一点也不好用,连区间修改都没有 。 等集训完了要静心好好系统的学习一下线段树 。 多看多刷lrj的书 。细节参见代码:#includeusing namespace

2015-08-14 21:02:02 883

原创 hdu-5025 Saving Tang Monk (BFS + 状态压缩)

该是比较简单的BFS的 。    难点在于多了两个限制条件 : 必须按照顺序捡拾钥匙 ; 杀死蛇消耗2单位时间,蛇只会被杀死一次 。因为在拿到第n把钥匙前必须拿到第n-1把,所以只需要加一维大小是11的维度来维护当前拿到的钥匙情况就可以完整的表示所有状态了 。但是还有蛇的条件,所以不妨在结构体里加一个正数,将其压缩成一个集合表示第i只蛇是不是被杀死了 。  所以事先对所有的蛇进行编号就行了

2015-08-14 19:39:16 1000

原创 11882 - Biggest Number(DFS + 剪枝)

网上很多人都是用的DFS加上BFS判断后续结点最大数量然后用来剪枝, 我只是用了DFS就过了~其实方法很简单,收到了例题 “万圣节后的早晨” 一题的启发,其实矩阵中有很多无用的障碍格,所以在搜索的时候就会多出很多无用的判断 。 因此我们不妨将有用的格子提出来再建一张图,然后DFS,如果只是这样发现会超时,其实对于一个样例来说最浪费时间的情况是:当前答案的长度为所有格子数时,不可能有其他更长的了

2015-08-13 10:47:07 1923

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除