dfs 算法的使用

来源:互联网 发布:淘宝刷买家秀平台 编辑:程序博客网 时间:2024/06/01 09:44
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的思想!

0 0
原创粉丝点击