dfs 算法的使用
算法思想,dfs算法是一个递归的过程,有回退的过程,对于一个无向连通图,访问图中某个顶点v0后,然后访问它的某一个邻接顶点v1,然后再从v1出发,访问v1的违访问过的邻接顶点,如此下去,直至到达所有的领接顶点都被访问过。然后回退一步,回到前一次被访问的顶点,看是否还有没有访问的顶点,如果有,则从这个顶点出发,进行向上述的过程一样进行访问,如果没有,则再回退一步,进行类似的访问,直至所有的顶点都被访问为止!- dfs算法用伪码来实现。
1.如果图是用邻接表存储
dfs(顶点i)
{
visited[i]=1;
p是i的边链表表头指针
while(p非空)
{
if(i顶点对应的另一个顶点没有被访问过,设为k)
{
递归搜索前要准备的工作的代码在这些
dfs(k);
回退过程中,应该在这里写代码!
}
p=p->next;
}
2 如果图是用邻接矩阵存储
dfs(顶点i)
{
visited[i]=1;
for(j=0;j<n;j++)
{ if(edge[i][j]<inf&&visited[j]!=1) //如果i到k之间有边链接,并且j没有被访问过
{ dfs(j);
}
}
}
- 应用:来自南阳理工学院oj平台(非常适合初学者在上面刷题)附上链接http://acm.nyist.net/JudgeOnline/problemset.php 题目是第42题,一笔画问题,该题主要是用 欧拉通路问题,用到了dfs搜索!
1 #include<cstdio> 2 #define maxn 1001 3 #include<memory.h> 4 struct anode 5 { 6 int to; 7 // int adj; 8 struct anode* next; 9 }; 10 anode* list[maxn]; 11 int visited[maxn]; 12 int n,m; 13 void dfs(int start) 14 { 15 anode *p; 16 p=list[start]; 17 visited[start]=1; 18 while(p) 19 { 20 if(!visited[p->to]) 21 { 22 dfs(p->to); 23 } 24 p=p->next; 25 } 26 27 } 28 int fun2() 29 { 30 int i; 31 for(i=1;i<=n;i++) 32 { 33 if(visited[i]==0) 34 return 0; 35 break; 36 } 37 return 1; 38 } 39 void fun() 40 { 41 int jdnum=0; 42 //int start1,start2; 43 anode *p; 44 int i; 45 for(i=1;i<=n;i++) 46 { 47 int dnum=0; 48 p=list[i]; 49 while(p) 50 { 51 dnum++; 52 p=p->next; 53 } 54 if(dnum%2!=0) 55 { 56 jdnum++; 57 } 58 } 59 if(fun2()==0) 60 printf("No\n"); 61 else 62 { 63 if(jdnum!=0&&jdnum!=2) 64 { 65 printf("No\n"); 66 } 67 else 68 printf("Yes\n"); 69 } 70 71 } 72 73 int main() 74 { 75 int kase; 76 // freopen("a.txt","r",stdin); 77 scanf("%d",&kase); 78 while(kase--) 79 { 80 scanf("%d%d",&n,&m); 81 anode *p1,*p2; 82 int v1,v2,i; 83 memset(visited,0,sizeof(visited)); 84 memset(list,0,sizeof(list)); 85 for(i=0;i<m;i++) 86 { 87 scanf("%d%d",&v1,&v2); 88 p1=new anode; 89 p2=new anode; 90 p1->to=v2; 91 p1->next=list[v1]; 92 list[v1]=p1; 93 p2->to=v1; 94 p2->next=list[v2]; 95 list[v2]=p2; 96 } 97 dfs(v1); 98 //fun2(); 99 fun(); 100 } 101 return 0; 102 103 } 104
其中dfs()函数是用来判断这个图是否连通,该题的图是用到邻接表来存储的,这样就不至于超时!
另外在附上一题用dfs来做同样来自南阳理工学院第27题
1 2 #include<stdio.h> 3 int grid[101][101]; 4 int m,n; 5 int dir[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; 6 void dfs(int x,int y) 7 { 8 int i,xx,yy; 9 grid[x][y]=0; 10 for(i=0;i<4;i++) 11 { 12 xx=x+dir[i][0]; 13 yy=y+dir[i][1]; 14 if(xx<0||yy<0||x>m||y>=n) 15 continue; 16 if(grid[xx][yy]==1) 17 dfs(xx,yy); 18 } 19 } 20 int main() 21 { 22 int i,j; 23 int h,count; 24 scanf("%d",&h); 25 while(h--) 26 { 27 scanf("%d%d",&m,&n); 28 for(i=0;i<m;i++) 29 { 30 for(j=0;j<n;j++) 31 scanf("%d",&grid[i][j]); 32 } 33 count=0; 34 for(i=0;i<m;i++) 35 { 36 for(j=0;j<n;j++) 37 { 38 if(grid[i][j]==1) 39 { 40 dfs(i,j); 41 count++; 42 } 43 } 44 45 } 46 printf("%d\n",count); 47 } 48 return 0; 49 } 50
这题纯粹是用dfs来解题,能够很好的体现dfs的思想!