CSU 1660 搜索 在图中寻找一个长度为K的环
2016-08-11 14:22
316 查看
题目的大概意思就是在给出的图里面寻找一个长度为K的环。。。
想了一想,肯定是用DFS,然后就考虑实现,可是以什么作为参数呢,以下是我考虑不恰当的地方:
我考虑的DFS参数有3个,第一个是当前的位置,还有一个是余剩的步数(我想到最多只能够走K次),还有一个是此次搜索的起点。
剪枝:跳过度为1的点,因为度为1的点不可能处于环上
我自己也认识到,这样的搜索有很大的重复性,比方说我从一个节点A向下寻找,在K步之内没有找到,接下来我会去在A+1处调用DFS,假若A和A+1相邻,此时所做的很大一部分工作是重复的,因为从A向A+1这边搜索的时候,已经搜索过一部分了,现在再搜索也仅仅是比原来多走一步而已。我想把走过的步数记录下来,可是没有想到好的办法,结果TLE到比赛结束。
比赛完之后去看题解发现自己没法实现的东西轻易的就可以实现。。。不得不说有点遗憾?
这个DFS里面有三个参数,第一个是当前的节点,第二个是离源节点的步数,第三个是父节点(也就是从哪边过来的)
在DFS搜索里面用来表示是否访问过的VIS数组来表示这个是离调用点有多少步,访问到某一个点P时,假若P已经访问过了,那么就把VIS里保存的步数取出来和当前的步数相比较,假若是K的话,那么就表明经过了一个环了。假若不是K,那么继续调用DFS。
这样的好处是一次可以搜索完一个连通子图,而不用像我之前那样对每一个节点都调用,显然要少做很多的重复性工作。以下是AC的代码,同样有跳过度为1的点的剪枝
为了做比较,我把之前的TLE的代码也贴出来
这样写完之后,感觉自己的想法也清晰了很多。。
补充:虽然我说的第一种解法很好,可是第一种解法是仅仅针对于部分的情况,由于CSUOJ的数据的问题,导致有一些情况无法正常的判断出来,比如说http://blog.csdn.net/nameofcsdn/article/details/52184252 这儿的给出的一个数据反例,经测试我说的AC代码是无法正常运行出正确的结果,可是用我原来的搜索代码就可以得到正确的答案,看来我考虑问题还是应该要深入一些才好。
想了一想,肯定是用DFS,然后就考虑实现,可是以什么作为参数呢,以下是我考虑不恰当的地方:
我考虑的DFS参数有3个,第一个是当前的位置,还有一个是余剩的步数(我想到最多只能够走K次),还有一个是此次搜索的起点。
剪枝:跳过度为1的点,因为度为1的点不可能处于环上
我自己也认识到,这样的搜索有很大的重复性,比方说我从一个节点A向下寻找,在K步之内没有找到,接下来我会去在A+1处调用DFS,假若A和A+1相邻,此时所做的很大一部分工作是重复的,因为从A向A+1这边搜索的时候,已经搜索过一部分了,现在再搜索也仅仅是比原来多走一步而已。我想把走过的步数记录下来,可是没有想到好的办法,结果TLE到比赛结束。
比赛完之后去看题解发现自己没法实现的东西轻易的就可以实现。。。不得不说有点遗憾?
这个DFS里面有三个参数,第一个是当前的节点,第二个是离源节点的步数,第三个是父节点(也就是从哪边过来的)
在DFS搜索里面用来表示是否访问过的VIS数组来表示这个是离调用点有多少步,访问到某一个点P时,假若P已经访问过了,那么就把VIS里保存的步数取出来和当前的步数相比较,假若是K的话,那么就表明经过了一个环了。假若不是K,那么继续调用DFS。
这样的好处是一次可以搜索完一个连通子图,而不用像我之前那样对每一个节点都调用,显然要少做很多的重复性工作。以下是AC的代码,同样有跳过度为1的点的剪枝
#include <cstdio> #include <cstring> #include <vector> using namespace std; vector<int> v[55]; int vis[55],n,m,x,y,t,k; bool flag,_find(int now,int pos,int pre); int main(){ scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;++i) scanf("%d%d",&x,&y),v[x].push_back(y),v[y].push_back(x); for(int i=0;i<n;++i) if(v[i].size()>1&&_find(i,1,-1)) flag=true,i=n; printf("%s\n",(flag)?"YES":"NO"); flag=false;memset(vis,0,sizeof(int)*n); for(int i=0;i<n;++i) v[i].clear(); } return 0; } bool _find(int now,int pos,int pre){ if(vis[now]) return pos-vis[now]==k; vis[now]=pos; for(int i=0;i<v[now].size();++i) if(v[now][i]!=pre&&v[v[now][i]].size()>1&&_find(v[now][i],pos+1,now)) return true; return false; }
为了做比较,我把之前的TLE的代码也贴出来
#include<cstdio> #include<vector> #include<cstring> using namespace std; int t,n,m,k,x,y; vector<int> v[55]; bool _find(int pos,int remain,int recourse),flag=false; int visi[55]; int main(){ scanf("%d",&t); while(t--){ scanf("%d%d%d",&n,&m,&k); for(int i=0;i<m;++i) scanf("%d%d",&x,&y),v[x].push_back(y),v[y].push_back(x); //printf("%d\n",v[0].size()); for(int i=0;i<n;++i) if(v[i].size()>1&&_find(i,k,i)){ flag=true; break; } printf("%s\n",(flag)?"YES":"NO"); for(int i=0;i<n;++i) v[i].clear(); flag=false;memset(visi,0,sizeof(visi)); } return 0; } bool _find(int pos,int remain,int recourse){ if(remain<=0) return false; visi[pos]=1; for(int i=0;i<v[pos].size();++i){ if(visi[v[pos][i]]==1&&v[pos][i]==recourse&&remain==1) return true; else if(v[v[pos][i]].size()>1&&visi[v[pos][i]]==0){ if(_find(v[pos][i],remain-1,recourse)) return true; } } visi[pos]=0; return false; }
这样写完之后,感觉自己的想法也清晰了很多。。
补充:虽然我说的第一种解法很好,可是第一种解法是仅仅针对于部分的情况,由于CSUOJ的数据的问题,导致有一些情况无法正常的判断出来,比如说http://blog.csdn.net/nameofcsdn/article/details/52184252 这儿的给出的一个数据反例,经测试我说的AC代码是无法正常运行出正确的结果,可是用我原来的搜索代码就可以得到正确的答案,看来我考虑问题还是应该要深入一些才好。
相关文章推荐
- CSU 1660 K-Cycle(dfs判断无向图中是否存在长度为K的环)
- 给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?
- 遗传算法与直接搜索工具箱学习笔记 五-----使用GPS算法寻找一个函数的最小值
- [LintCode 382]给定一个整数数组,在该数组中,寻找三个数,分别代表三角形三条边的长度,问,可以寻找到多少组这样的三个数来组成三角形?
- 遗传算法与直接搜索工具箱学习笔记 五-----使用GPS算法寻找一个函数的最小值
- 如何最简单的搜索一个未知长度链表的倒数第k位。
- 列出SQL SERVER 所有表、字段定义,类型,长度,一个值等信息,并导出到Excel 中
- WSS[sharepoint]中如何建立一个搜索的功能的webpart[Search]
- 一个查找文件的类:它的长处在于能够搜索子目录并且是可控制的
- 一个时间转换的问题,顺便谈谈搜索技巧
- ASP编写完整的一个IP所在地搜索类
- 寻找一个合适递归时,问自己这么一个问题...
- 原来做的一个语义搜索软件的界面
- (转)列出SQL SERVER 所有表、字段定义,类型,长度,一个值等信息(另一种方法)
- 发起一个桌面搜索项目
- 一个时间转换的问题,顺便谈谈搜索技巧
- 一个有趣的查找--搜索最大值所在的ID号 (轉自:http://blog.csdn.net/dhlhh)
- AspNetCommerce中的一个带分页和排序的搜索功能的存储过程
- google里搜索电子书的一个好办法
- AspNetCommerce中的一个带分页和排序的搜索功能的存储过程