摘要: 终于找到了T^Thttp://code.google.com/p/aoapc-book/ 阅读全文
posted @ 2013-08-31 19:13 Thousand Sunny 阅读(509) 评论(0) 推荐(0) 编辑
摘要: 题意:人与人交友构成关系网,两个人交友,相当于两个朋友圈的合并,问每个出两人,他们目前所在的关系网中的人数。分析:用并查集,其实就是求每个集合当前的人数。对于人名的处理用到了字典树。注意:1、题目给出的n是指n对关系,上限有2*n个人。 2、题目很没有意思的既说了有多组数据,又要求输入组数。实际上还是多组数据。 1 #include 2 #include 3 #include 4 using namespace std; 5 6 const int MAXN=200002; 7 8 struct Node{ 9 int c;10 Node *child[52];11 ... 阅读全文
posted @ 2013-10-24 13:39 Thousand Sunny 阅读(363) 评论(0) 推荐(0) 编辑
摘要: 题意:有一种叫作Pseudoforest的结构,表示在无向图上,每一个块中选取至多包含一个环的边的集合,又称“伪森林”。问这个集合中的所有边权之和最大是多少?分析:如果没有环,那么构造的就是最大生成森林,在此基础上,只要取每个块中剩余边的最大边,必然得到结果。不过要构造出每条边归属于哪个块。 看了别人的代码,发现原来可以直接构造出一个标记数组记录环,在做并查集的时候扩充if(find(u)==find(v))这一条件,可以直接得到结果。 1 #include 2 #include 3 #include 4 using namespace std; 5 6 const int MAXN=1... 阅读全文
posted @ 2013-10-23 15:05 Thousand Sunny 阅读(241) 评论(0) 推荐(0) 编辑
摘要: 题意:在一张无向图上,已知边权,做q组询问,问小于L的点对共有几组。点对间的距离取=min(两点之间每一条通路上的最大值)。分析:这里取最大值的最小值,常用到二分。而这里利用离线算法,先对边从小到大排序,逐一加入集合中。利用并查集,当两点之间不在同一个集合,那么所加入的边就是两个集合中任一点对的距离(两集合各取一点)。所以有cnt2+=num[fu]*num[fv];注意:有些询问比m条边中的最小边还小,比最大边还大。 1 #include 2 #include 3 #include 4 using namespace std; 5 6 const int MAXN=11111; 7 8 .. 阅读全文
posted @ 2013-10-20 14:46 Thousand Sunny 阅读(403) 评论(0) 推荐(0) 编辑
摘要: 题意:略分析:排序先按rating,若相同,则按rp。考虑到每个人的rp均不同,所以rating相同的人必然可以排序。那么只需要考虑rating不同的集合了。 大小关系可以用有向边表示,而大小关系的传递可以用拓扑排序来呈现。 接着就要分析,三种结果对应的情况了。 很明显,ok要求拓扑出来的必须是一条链,一旦有分支,分支处的两个(或多个)点的大小关系就不明确,也就是条件不足=>uncertain。 而矛盾conflict有两种情况:1、更改关系0=1,0>1;2、自相矛盾,即成环,0>1,0 2 #include 3 #include 4 #include 5 #incl... 阅读全文
posted @ 2013-10-19 16:26 Thousand Sunny 阅读(207) 评论(0) 推荐(0) 编辑
摘要: 题意:略分析:多询问问题,利用并查集加速。类似于kruskal对MST的构建:枚举最小的边,逐渐将更大的边加入集合,当查询的点在同一个集合,那么当前最小值,就是所加的最后一条边与第一条只差。注意:当枚举的最小边,把所有大边加入都不能使查询点(a,b)加入同一集合,那么终止枚举。 1 #include 2 #include 3 #include 4 using namespace std; 5 6 const int MAXN=1111; 7 const int INF=0x7fffffff; 8 9 struct Edge{10 int u,v,c;11 Edge(... 阅读全文
posted @ 2013-10-16 16:33 Thousand Sunny 阅读(184) 评论(0) 推荐(0) 编辑
摘要: 题意:给出n个人的属性(a,b),当A(a,b)与B(a',b')存在关系:(ax1)查找,所有(y2>y1)的点(x2,y2)都失去优势,从集合中删除。注意:若左侧没有点it==s.begin(),必然可以加入。 1 #include 2 #include 3 using namespace std; 4 5 struct P{ 6 int x,y; 7 bool operator s;13 multiset::iterator it;14 15 int main()16 {17 int T,n;18 scanf("%d",&T);19 .. 阅读全文
posted @ 2013-10-16 15:03 Thousand Sunny 阅读(245) 评论(0) 推荐(0) 编辑
摘要: 题意:(理解错了)在一个洞穴中有多个room,要求任意选两个room:u、v,都能保证u、v之间有通路,注意洞穴中的路是有向边。、分析:强连通子图中的点必然两两之间可以互通,两个强连通子图之间有通路,必须在树上构成父子关系(不一定相邻),又两两之间有通路,即任意两个点u、v都存在父子关系——所有强连通子图构成一条链。错误:tarjin初始化忘记更新scc_cnt=dfs_clock=0; 1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7 using namespace std; 8 9 c... 阅读全文
posted @ 2013-10-05 13:11 Thousand Sunny 阅读(479) 评论(0) 推荐(0) 编辑
摘要: 题意:要把一块n*m*k的巧克力分成1*1*1的单元,有两种操作方式:1,用手掰(假设力量无穷大),每次拿起一块,掰成两块小的;2,用刀切(假设刀无限长),可以把多块摆在一起,同时切开。问两种方式各需多少次操作才能完成任务。分析:用手掰很明显是(n*m*k-1)次操作。用刀切注意不是((n-1)+(m-1)+(k-1))次操作,这只是不动原巧克力的操作数。举个例子:1*1*4的巧克力,用刀切,按上面说的要3次操作,实际上只需2次。所以不管是长宽高,都只需要[log2n](或m,k)次操作。注意:数据范围上限是2000,n*m*k后超出231的范围,__int64 1 #include 2 #i 阅读全文
posted @ 2013-10-04 19:54 Thousand Sunny 阅读(239) 评论(0) 推荐(0) 编辑
摘要: 题意:已知起点、圆、矩形,要求计算从起点开始,经过圆(和圆上任一点接触即可),到达矩形的路径的最短距离。(可以穿过园)。分析:没什么好的方法,凭感觉圆上的每个点对应最短距离,应该是一个凸函数,用三分来解。不过应该是分成两部分,用两次三分来解。具体原因不明,通过实验只能得出三分必须是针对一个凸函数,很明显,从0~2*pi不是一个凸函数,但同理,0~pi,pi~2*pi也不一定是个凸函数。个人认为,网络上流传的[0,pi][pi,2*pi]这种分法,并不存在合理性。继续思考= = 另外,直接暴力枚举也是能过的。错误:分析圆上的点与矩形的位置关系写挫了,虽然现在还是研究不明白到底出了什么问题,应.. 阅读全文
posted @ 2013-10-04 19:42 Thousand Sunny 阅读(232) 评论(0) 推荐(0) 编辑
摘要: 题意:给出一个有向图G,寻找所有的sink点。“sink”的定义为:{v∈V|∀w∈V:(v→w)⇒(w→v)},对于一个点v,所有能到达的所有节点w,都能够回到v,这样的点v称为sink。分析:由(v→w),(w→v)可知,节点v,w构成强连通,很自然的想到要缩点。缩点之后,DAG上的每一条边,都是单向的(v->w),无回路(w->v)。错误:对于v可达的点w,不仅是直接连边——从一个强连通子集A到另一个强连通子集B,意味着,子集A中的点都不可能是sink点。 1 #include 2 #include 3 #include 4 #include 5 using namespac 阅读全文
posted @ 2013-10-03 12:01 Thousand Sunny 阅读(216) 评论(0) 推荐(0) 编辑