【算法】深度优先搜索(DFS)I
来源:互联网 发布:mac win10 iso 下载 编辑:程序博客网 时间:2024/04/28 04:31
1. 算法描述
DFS(depth first search)的算法思想非常朴素:对点u,访问与u相连的某点u1,再访问与u1相连的某点u2,……依次由浅入深地访问相连节点。基本步骤如下:
(1)访问点u;
(2)若与点u相连的点u1未被访问,则递归地访问u1的相连节点。
DFS的递归实现:
void dfs(int u,struct ALGraph *gra){struct ArcNode *p;visit[u]=1;for(p=gra->Gvertex[u].firstarc;p!=NULL;p=p->next)if(!visit[p->adjvex])dfs(p->adjvex,gra);}
代码中,图是用邻接表存储。如果用栈来维护已访问的节点,DFS有非递推实现:
2. 应用
DFS无论是在图论中,还是在其他问题中都有着非常广泛的应用,常见的有:
2.1 判断两点之间的可达性
由点u开始,经过DFS遍历后,若点v未被访问,则说明点u到点v不可达;反之,则否。问题有,
(1)POJ 3256 求点x满足图中的k个点对其均可达。
2.2 生成组合
组合,就是在n个数中取k个数,共有C(n, k)种取法。如果要遍历这C(n, k)种取法,是一个比较困难的问题,可以用DFS加以模拟。问题有
(1)POJ 3628 n个数中取若干个数相加,满足相加之和大于B,求相加之和为最小的那一个组合。
(2)POJ 2245 给出k个数,遍历c(k, 6)的组合。
(3)POJ 1564 给出有重复的n个数,选取若干数使得和为t,求所有的选取情况。
(4)POJ 1011 将n个数分成若干个组,且每组内的数相加之和为x,求最小的x。
(5)POJ 2362 给一些棒子,求能否摆成一个正方形。
(6)POJ 1040 带限制条件,求从t个订单选出若干个订单使得收益最大。
(7)POJ 2531 对分属两个集合的节点,求如何分配集合使得两两之间距离之和的最大值。
2.3 生成排列
排列,就是在n个数中有顺序地取出k个数,共有A(n, k)种取法。当取n个数时,称该问题为全排列问题。问题有
(1)POJ 2907 遍历n个点的全排列,求最短路径。
(2)POJ 1256 求带重复元素的全排列。
(3)POJ 1270 拓扑排序。
(4)POJ 2367 带限制条件的全排列。
2.4 求连通分支
从某一点开始DFS,直至结束,此为一个连通分支;再从另一个未被访问的点开始DFS……即可求出连通分支数。问题有POJ 2386 1562 。
2.5 遍历
暴力遍历所有可能情形,可用来解决“骑士游历”、“八皇后问题”、“数独问题”。其中,后两个问题的解决可以用DLX算法进行优化。
3. Referrence
[1] Felicia Crazy, Powerful Algorithm - DFS.
4. 问题
4.1 POJ 3256
题目大意:图中的k个点对点x均可达,求满足这样可达性条件的点x有多少个。
思路:DFS可用来判断两点之间的可达性。但是,如果依次判断图中每个点是否满足可达性条件,那么算法复杂度较高。可以对DFS稍作修改:用num[ i ]记录点i在DFS中被访问的次数;k个点DFS之后,如果num [ i ]==k,则说明k个点对点i均可达。
源代码:
3256Accepted504K79MSC1370B2013-10-05 15:07:13
#include "stdio.h"#include "string.h"#define MAXK 100#define MAXN 1001struct ArcNode {int adjvex;struct ArcNode *next;};struct VNode {int vertex;struct ArcNode *firstarc;};typedef struct ALGraph{int k,n,m;struct VNode Gvertex[MAXN];}ALGraph;int cows[MAXK],visit[MAXN],num[MAXN];void CreateGraph(ALGraph *gra){int k,n,m;int i,start,end;struct ArcNode *p=NULL;scanf("%d%d%d",&k,&n,&m);gra->k=k; gra->n=n; gra->m=m; for(i=0;i<k;i++)scanf("%d",&cows[i]);for(i=1;i<=n;i++){gra->Gvertex[i].vertex=i;gra->Gvertex[i].firstarc=NULL;}for(i=1;i<=m;i++){scanf("%d%d",&start,&end); p=(struct ArcNode *) malloc(sizeof(struct ArcNode));p->adjvex=end;p->next=gra->Gvertex[start].firstarc;gra->Gvertex[start].firstarc=p;}}void dfs(int u,struct ALGraph *gra){struct ArcNode *p;visit[u]=1;num[u]++;for(p=gra->Gvertex[u].firstarc;p!=NULL;p=p->next)if(!visit[p->adjvex])dfs(p->adjvex,gra);}int main(){int i,count=0;ALGraph *gra=(ALGraph *) malloc(sizeof(ALGraph));CreateGraph(gra);memset(num,0,sizeof(num));for(i=0;i<gra->k;i++){memset(visit,0,sizeof(visit));dfs(cows[i],gra);}for(i=1;i<=gra->n;i++)if(num[i]==gra->k)count++;printf("%d\n",count);}
4.2 POJ 3628
题目大意:给定一个数B和一组数h[ ],h[ ]满足其中部分数相加之后大于B,求在比B大的所有组合中最小的那一个。
基本的DFS,遍历所有的相加可能情形,求出最小的那一个。
源代码:
3628Accepted164K32MSC542B2013-10-05 21:29:13
#include "stdio.h"#include "stdlib.h"#include "limits.h"int cmp(const void *a,const void *b){return (*(int *)b-*(int *)a);}int N,B,h[20],minimum;void dfs(int depth,int sum){if(depth==N+1||minimum==0)return;if(sum>=B)minimum=minimum<sum-B ? minimum: sum-B;dfs(depth+1,sum);dfs(depth+1,sum+h[depth]);}int main(){int i;minimum=INT_MAX;scanf("%d%d",&N,&B);for(i=0;i<N;i++)scanf("%d",&h[i]);qsort(h,N,sizeof(int),cmp);dfs(0,0);printf("%d\n",minimum);return 0;}
4.3 POJ 2245
题目大意:给出k个数,从k个数取6个数,求生成c(k, 6)的组合。
标准的DFS,用到了剪枝。语句dfs(depth+1,num+1); 与语句 dfs(depth,num+1); 的顺序不能颠倒。
源代码:
2245Accepted164K16MSC494B2013-10-06 15:05:38
#include "stdio.h"#include "stdlib.h"int k,subset[12],result[6];void dfs(int depth,int num){int i;if(num>k||k-num+depth<6) //剪枝,判断剩下的数是否还足以拼成return;if(depth==6){for(i=0;i<5;i++)printf("%d ",result[i]);printf("%d\n",result[5]);return;}result[depth]=subset[num];dfs(depth+1,num+1);dfs(depth,num+1);}int main(){int i;while(scanf("%d",&k)&&k){for(i=0;i<k;i++)scanf("%d",&subset[i]);dfs(0,0);printf("\n");}return 0;}
- 【算法】深度优先搜索(DFS)I
- (DFS算法)深度优先搜索算法
- 【算法】深度优先搜索(DFS)II
- 【算法】深度优先搜索(DFS)III
- 【算法】深度优先搜索(DFS)IV
- 【算法】深度优先搜索(DFS)V
- 【算法】深度优先搜索(DFS)VI
- 深度优先搜索算法(DFS)
- 深度优先搜索(DFS)算法
- 深度优先搜索(DFS)算法
- 算法 DFS深度优先搜索
- DFS(深度优先搜索算法)
- 深度优先搜索(DFS)算法
- DFS深度优先搜索算法
- 深度优先搜索(DFS) 算法
- DFS深度优先搜索算法
- 深度优先搜索DFS算法
- 深度优先DFS搜索算法
- hdu2222 Keywords Search (AC自动机)
- UVA - 11489 Integer Game
- vb.net 关于log的简单代码
- 数据结构C++算法实现2 - 归并排序1
- 金融系统中PBOC/EMV的TLV的算法实现(含C++/C#)
- 【算法】深度优先搜索(DFS)I
- 让你的开发变得更加快起来
- 2013年长沙网络赛G题
- Spring如何处理线程并发
- 登山
- 新建项目(failed to import..)解决方法
- ios页面间传递参数四种方式
- 组合数递推模版
- 自己写代理服务器