上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 23 下一页
摘要: 该算法也是tarjan发现的,故也叫tarjan算法。这个算法的主体还是dfs,先看算法框架:void make_set(int i){p[i]=i;}int find_set(int i){if(i!=p[i])p[i]=find_set(p[i]);return p[i];}union_set(int i,int j){i=find_set(i),j=find_set(j);p[j]=i;}//tarjan算法主体void dfs(int u){int i,v;make_set(u);for(i=0;i<g[u].size();i++){v=g[u][i];if(p[v]==-1){ 阅读全文
posted @ 2012-07-07 08:32 BeatLJ 阅读(3637) 评论(0) 推荐(1) 编辑
摘要: tarjan算法的基本框架就是dfs,其基本原理是有向图至少存在一棵深搜子树,其结点集合构成一个强连通分量,这是显然的,因为必定有一个强连通分量最后被dfs,这个强连通分量的结点构成深搜树的一棵子树。有了以上结论后,求强连通分量就有思路了,我们在每棵子树深搜完成后判断这棵子树是否构成强连通分量即可,关键在于如何判断一棵子树是否构成强连通分量。注意到最先搜索完的子树是那些叶子结点,要判断叶子结点是否构成强连通分量很简单,若存在叶子结点与其祖先结点的连边,则该叶子结点不构成强连通分量,否则构成强连通分量。tarjan算法用pre[V]数组和low[V]数组来判断子树是否构成强连通分量,pre[v] 阅读全文
posted @ 2012-07-07 08:31 BeatLJ 阅读(964) 评论(0) 推荐(0) 编辑
摘要: 第一遍dfs是对原图进行,求出每个结点的后序遍历顺序,也叫时间戳,注意保存方式,应该是保存每个时间点的访问的结点,而不是保存每个结点的访问时间;第二遍dfs是对逆图进行,根据第一遍dfs的结果,首先在逆图上从时间戳最大的结点开始dfs,可以得到第一个强连通分量,将遍历过的结点标记,然后从下一个时间戳最大的且尚未标记的结点开始dfs,可以得到第二个强连通分量,以此类推,直到所有结点都确定其所在的强连通分量,此时算法结束。首先分析由此算法得到的第一个强连通分量的正确性,易知时间戳最大的是有向图的根结点:1、从根结点出发,可以到达所有结点;2、第二遍dfs是在逆图上进行的,所以第二遍dfs得到的是所 阅读全文
posted @ 2012-07-05 12:15 BeatLJ 阅读(1615) 评论(0) 推荐(0) 编辑
摘要: Description在一个8行9列的国际象棋棋盘上,有一名骑士在追杀对方的国王。该骑士每秒跨越一个2*3的区域,如下图所示。而对方的国王慌忙落逃,他先沿着右下斜线方向一直跑,遇到边界以后会沿着光线反射方向继续跑(遇到死角则原路返回),他每秒只跑一格。给出骑士和国王的初始位置,求最快在多少秒的时候骑士能追杀掉对方的国王。骑士和国王每一秒都必须要有行动,而不能原地等待。Input有多组测试数据。对于每组测试数据,输入只有一行:nx,ny,kx,ky,前2个表示骑士的初始坐标,后2个表示国王的初始坐标,以左上角的格子为(0,0),向右为x轴正方向,向下为y轴正方向。(0<=nx,kx< 阅读全文
posted @ 2012-07-03 18:41 BeatLJ 阅读(216) 评论(1) 推荐(0) 编辑
摘要: 求一棵树中2个点的最近公共祖先。我的做法:用并查集求出每个结点的深度,然后递归求最近公共祖先。View Code 1 #include <stdio.h> 2 #define N 10001 3 int fa[N],p[N],d[N],n; 4 void make_set() 5 { 6 for(int i=1;i<=n;i++) 7 { 8 p[i]=i; 9 d[i]=0;10 }11 }12 int find_set(int i)13 {14 int pi=p[i];15 if(pi!=i) p[i]=find_set(p[i]);16 if(p... 阅读全文
posted @ 2012-07-03 18:29 BeatLJ 阅读(235) 评论(0) 推荐(0) 编辑
摘要: Description中南大学ACM的暑期集训马上就要开始了,这次集训会将全体N名集训队员(编号分别为1, 2, …, N)按集训选拔赛的排名分成两组,前K名队员分入A组,其余队员分入B组。但现在助理教练CSGrandeur一不小心把集训选拔赛的排名弄丢了,而之前又没将A组和B组的人员确定出来,于是CSGrandeur打算问一下集训人员他们的名次各是怎样的,以此来确定一下A组的队员。然而集训队员们都视名次如粪土,只是隐约记得某些人排在了自己的后面,最终反馈到CSGrandeur这里的一共有M条信息,每条信息都可以用一个二元组(x, y) (x!=y)表示,含义为第x名队员记得第y名队员的排名比 阅读全文
posted @ 2012-07-02 19:40 BeatLJ 阅读(311) 评论(0) 推荐(0) 编辑
摘要: 标准PSO算法的C语言实现。测试函数为y=x*sin(10*PI*x)+2,x取值范围[-1,2],求最大值。View Code 1 /* 2 用粒子群算法求函数最值测试 3 测试函数为 y=x*sin(10*pi*x)+2 4 x取值范围[-1, 2] 5 */ 6 #include <stdio.h> 7 #include <math.h> 8 #include <time.h> 9 #include <stdlib.h>10 11 #define MAX(a,b) ((a)>(b)?(a):(b))12 #define PI 3.14 阅读全文
posted @ 2012-05-26 22:11 BeatLJ 阅读(2153) 评论(0) 推荐(1) 编辑
摘要: 最近在写遗传算法求TSP时看到了grefenstette编码,于是想起了这个题目,这题我原来是用线段树写的C语言提交的,用时157ms,刚用树状数组+二分写用C++提交只跑了47ms,感觉快了不少。这题数学模型是:现有一个1到n的一个被打乱的排列,告诉你每个数的左边有多少个数比它小,显然第一个数左边没有比它小的数,求每个位置上的数。grefenstette编码差不多,只是把左边改成了右边再加1,例如:8 6 7 5 3 4 1 2编码后是:8 6 6 5 3 3 1 1View Code 1 #include <stdio.h> 2 #include <string.h> 阅读全文
posted @ 2012-05-21 17:57 BeatLJ 阅读(379) 评论(0) 推荐(0) 编辑
摘要: 最近在做人工智能的课设,碰到一个与TSP类似的问题,今天尝试了一下用遗传算法求解TSP,下面是我碰到的问题以及我的一些想法:1.如何对个体进行编码?TSP问题的实质是求一个最短的哈密顿回路,如果将城市标号为0,1,2...n-1,那么TSP的一个解就是一个圆排列,等价于一个规定了起点的排列,所以容易想到可以用顺序编码方式,即用一个数组保存旅游顺序。2.如何快速初始化种群?根据上述编码方式,种群初始化就是产生一系列随机排列,c++有一个函数rand_shuffle(V.begin(),V.end())可以打乱一个排列,用这个可以实现种群的快速初始化。3.如何交叉?这个问题可以说是遗传算法求TSP 阅读全文
posted @ 2012-05-20 21:12 BeatLJ 阅读(676) 评论(0) 推荐(0) 编辑
摘要: 之前用matlab写过遗传算法,但从没用c实现过,今天老师布置了人工智能的课设,为了温故下学过的遗传算法,于是有了下面的代码……下面的代码是求y=x*sin(10*pi*x)+2 (-1<=x<=2)的(近似)最大值,但稍作修改即可求其他函数的最值。View Code 1 /* 2 用遗传算法求y=x*sin(10*pi*x)+2的最大值 -1=<x<=2 3 精确到6位小数 4 pow(2,21)<3*1000000<pow(2,22) 5 编码的二进制长度为22 6 */ 7 #include <stdio.h> 8 #include < 阅读全文
posted @ 2012-05-19 23:58 BeatLJ 阅读(9768) 评论(4) 推荐(2) 编辑
上一页 1 ··· 8 9 10 11 12 13 14 15 16 ··· 23 下一页