2011年8月15日
摘要: POJ_3159 一开始我想多了,有段时间就在想如果图不连通该添加一些什么约束条件。但后来突然发现,如果最后N和1不连通的话,那么这个题就无解了,想到这,题目就变的简单了,因为只有一个约束条件,d[A]-d[B]>=-c,然后将d[1]看做0,以1为起点求一个到N的最短路就可以了。 此外,这个题在用SPFA的时候,如果用循环队列会超时,而用栈就没有问题,具体的原理我也不清楚。#include<stdio.h>#include<string.h>int first[31000],next[151000],v[151000],w[151000];int s[31000 阅读全文
posted @ 2011-08-15 20:56 Staginner 阅读(248) 评论(0) 推荐(0) 编辑
摘要: POJ_2983有了前面做的题目的基础后,这个题目也还算比较好想到的。我们设S[i]为点i到直线上某参照点的距离(可以把0看做这个参照点),为了写起来方面,干脆把题目A north thanB全部想像成B south than A,那么如果是输入P的时候,就应该有两个约束方程S[B]-S[A]>=X,S[A]-S[B]>=-X,而输入V的时候,就只对应着一个约束方程S[B]-S[A]>=1。之后如果用最短路去做的话,实际上就是判断这个图是否存在负圈。为了使图连通起来,我们抽象出一个源点0,则对任意点i都有S[i]-S[0]>=0,这样便将图连通了起来,最后只要以0为起点 阅读全文
posted @ 2011-08-15 19:31 Staginner 阅读(292) 评论(0) 推荐(0) 编辑
摘要: POJ_1716 由于有了前面几个题目的基础,解答这个题目的过程还算顺利。我们设S[i]为区间[0,i)内选取的数字的数量,那么有①S[b+1]-S[a]>=2,②S[i+1]-S[i]>=0,③S[i]-S[i+1]>=-1。这样以max(b)+1为起点,以min(a)为终点求一个最短路就可以了,最后的结果为d[max(b)+1]-d[min(a)]。#include<stdio.h>#include<string.h>int first[10010],next[30010],v[30010],w[30010];int inq[10010],q[10 阅读全文
posted @ 2011-08-15 16:27 Staginner 阅读(339) 评论(0) 推荐(0) 编辑
摘要: POJ_1364这个题目其实还算是比较简单的差分约束系统的题目。一开始其实已经把输入数据的约束条件都找全了,如果设S[i]为[a1,ai]的和,那么如果符号是gt,则有S[ai+ni]-S[ai-1]>=ki+1,如果符号是lt,则有S[ai-1]-S[ai+ni]>=-ki+1。然后发现这个图可能从S[n]开始做最短路不是连通的,于是我便想加两个辅助条件S[i]-S[i-1]>=-INF,S[i]-S[i-1]<=INF,这两个条件是没有问题的,但可能是由于INF精度的问题而WA掉了。后来再看了别人的报告之后,发现其实让图连通不用这么麻烦。首先,做最短路没必要把S[n 阅读全文
posted @ 2011-08-15 15:41 Staginner 阅读(369) 评论(0) 推荐(0) 编辑
摘要: POJ_1275对差分约束系统还是有点摸不着头脑的感觉,看了别人的分析之后才把代码写了出来。首先这个题目可以做两个预处理,一个是在输入数据时找出R[i]的最大值,最后的结果一定是大于等于R[i]的,这样在枚举结果时就可以减少一部分工作量。另一个是在输入结束后,可以枚举8个小时的区间,如果这个区间里所有可雇用的人数加起来,还不足区间尾那个时间所需要的工人数,那么这种情况一定是无解的,反之,便一定是有解的。如果设S[i]为[0,i)这些时间内雇佣的总人数,那么可以列出下面几个差分约束方程:①S[i+1]-S[i]>=0;②S[i]-S[i+1]>=-t[i];③0<=j<= 阅读全文
posted @ 2011-08-15 02:48 Staginner 阅读(324) 评论(0) 推荐(0) 编辑
  2011年8月14日
摘要: POJ_1201第一次接触差分约束系统的题目,有点摸不着头脑,看了别人的解析后又觉得差分约束系统也好神奇呵!假以时日,我一定会掌握它!我们设S[i]为区间[0,i)之内的Z元素的数量,那么根据输入可以构成一个约束条件S[b+1]-S[a]>=c,另外还有两个隐含条件,S[i+1]-S[i]>=0,S[i+1]-S[i]<=1,实际上还有另外一个条件S[b+1]-S[a]<=b+1-a,但这个条件可以由S[i+1]-S[i]<=1推导出来,所以就不必管它了。然后把上面3个条件变形后得到S[b+1]+(-c)>=S[a],S[i]+0<=S[i+1],S[ 阅读全文
posted @ 2011-08-14 18:13 Staginner 阅读(326) 评论(0) 推荐(0) 编辑
  2011年8月13日
摘要: POJ_3177说实话,我现在还是不明白这个题目究竟是想让我们如何去处理问题。首先的疑惑就是如果连续输入两个1 2,1和2之间算一条路还是两条路,其次如果分别输入1 2及2 1,这时1和2之间算一条路还是两条路?由于对上面数据的理解的不同,会用3种不同的处理方式:①不管1 2还是2 1,就当做是1和2之间连通,也就是完全忽略题目中所说的两点之间可以有多条路,多条时只当有一条。②两个1 2看做一条路,1 2及2 1看做两条路。③两个1 2看做两条路,1 2及2 1也看做两条路。其中根据①和②写出的程序都是可以AC的,而根据③写出的程序,依据我看到的一些讨论,应该是WA掉的。也正是因为这个,导致我 阅读全文
posted @ 2011-08-13 20:33 Staginner 阅读(259) 评论(0) 推荐(0) 编辑
摘要: POJ_3352 这个题目和问最少添加多少条有向边使图成为一个强连通分量的题目有些类似,只不过题目的模型换成了边双连通分量的模型,我们同样可以用tarjan算法来解决,只不过相对于强连通分量的tarjan代码有稍许不同。由于题目中说明了各个点之间都是连通的,因而我们就不用再考虑孤立的点或者边双连通块了,只需要把最后的边双连通分量染色,求出各个所谓的是leaf的边双连通分量的个数,最后的答案就是(leaves+1)/2。所谓的“叶子”,就是针对一个边双连通分量来讲,它只和除自己之外的一个边双连通分量间存在一条无向边,那么这个边双连通分量就是所谓的“叶子”。至于最后的结果为什么是(leaves+1 阅读全文
posted @ 2011-08-13 17:15 Staginner 阅读(295) 评论(4) 推荐(0) 编辑
  2011年8月11日
摘要: POJ_2553这个题目本来是比较容易下手的,最后只需要求所有出度为0的强连通分量所包含的点,然后按字典序输出即可。但是由于一开始用邻接表写代码的时候由于读入边和存储边的写法问题导致我一直TLE,后来终于知道了怎么写才不会TLE,但是还是不太懂其中的原理,听群里人说是因为TLE的写法翻译成汇编语言会多出很多语句。因此,以后写代码的时候,还是尽量少在数组名里面再嵌套数组名。同时看了别人的代码还有一些额外的收获,就是在用邻接矩阵储存无权边时,用bool数组要比int的效率高,数据多时,即使在C里面用char数组都要比int数组的效率有明显的提高(大概20%,当然只是针对这个题目而言)。#inclu 阅读全文
posted @ 2011-08-11 22:55 Staginner 阅读(437) 评论(0) 推荐(0) 编辑
摘要: POJ_2186 这个题目其实就是求完强连通分量之后,判断一下出度为0的强连通分量是否唯一,如果唯一输出该强连通分量的点数,否则输出0。由于之前求强连通分量的时候是把同一个强连通分量里的数放到一个数组里,然后枚举各个数组之间各元素是否有边来判断各个强连通分量是否连通,由于这样效率比较低,这次超时了。后来看了别人的代码后发现,其实可以找到强连通分量之后,把其中的每个元素都染成一个颜色(开一个数组paint[]来记录染色情况,颜色用num表示,初始化为0),最后枚举所有边,如果一条边(u,v)两个端点的颜色不一样,那么就让outdgr[paint[u]]++。当然,这样最后outdgr中存的并不是 阅读全文
posted @ 2011-08-11 19:27 Staginner 阅读(337) 评论(0) 推荐(0) 编辑