DFS回溯遍历
2006-12-18 16:12
281 查看
以前想做DFS,不知道回溯怎么用代码实现,现在发现很简单,用回溯的递归就能搞定。 PKU ACM 3140,4107,1655,3099都是类似的例子。
好多问题都可能归结成当前子树的规模,DFS,就是对某一个节点的所有没有访问的子节点一个个访问,最后归结起来就能返回。
帖一些回溯的代码:下面的代码解决了三个问题:1:n皇后,2找出一个集合中所有满足某个条件的子集,3显示一个集合的所有子集。 注意变量数组的空间只需要一个就够了,因为是递归调用。
#include <iostream>
#include <cmath>
using namespace std;
int Num;
bool Place (int k, int i, int *x)
{
for(int j=0;j<k;j++)
if( (x[j]==i) || ( abs( x[j]-i)==abs(j-k) ) ) return false;
return true;
}
void NQueens(int k, int n, int *x)
{
for(int i=0; i<n;i++)
{
if( Place(k,i,x)) //»ØËÝ·¨£¬ÀûÓóÌÐò¾Íд³öËùÓпÉÄÜÐÔ£¬ÓÉÓÚÊǵ¥Ị̈߳¬ËùÒÔ»áÖ´ÐÐÍêÒ»¸öÔÙÖ´ÐÐÏÂÒ»¸ö£¬ËùÒÔ²»ÓÃ×Ô¼ºÐ´³ö»ØËÝ£¬ÎÒÒÔÇ°µ±³ÉÊ÷дÁË£¬¸´ÔÓµÄÌ«¶à
{ //²»ÐеĻ°£¬¾Í·ÅÆúÁËÒ»Ñù
x[k] = i;
if( k== n-1){
for(int m=0;m<n;m++)
cout << x[m]<<" ";
cout<<endl;
Num++;
}
else NQueens(k+1,n,x);
}
}
}
void NQueens(int n, int *x)
{
Num = 0;
NQueens(0,n,x);
cout<<Num<<endl;
}
int Get(int s, int wi,int D)
{
if( s + wi > D)
return 1;
else if( s + wi == D )
return 0;
return -1;
}
void Sum(int k, int n, int *x,int *out, int kk,int D, int s)
{ // ´ÓÔÊý×éµÚk¸ö¿ªÊ¼¼ÌÐøËÑË÷£¬ ÔÊý×én£¬*x
// *out kk ½á¹ûºÍ½á¹û½«Òª±£´æµÄϱê
// Ä¿±ê ºÍ ÏÖÔÚ״̬
for(int i=k; i<n;i++) // »ØËÝ·¨Ð§ÂÊÈçºÎ£¿
{
int tmp = Get( s, x[i],D);
if( tmp == 0 ) //ÏÔʾ³öÀ´
{
out[kk] = x[i];
for(int j=0;j<=kk;j++)
cout<<out[j]<<" ";
cout<<endl;
}
else if( tmp ==-1)
{
out[kk] = x[i];
if( i<n-1)
Sum(i+1,n,x,out,kk+1,D,s+x[i]); //Éî¶ÈÓÅÏÈ
}
else if( tmp ==1) //²»´¦Àí£¬Ï൱ÓÚ¼ôÈ¥ÁËÊ÷µÄÒ»¸öÖ§
{
}
}
}
void OnPaint(int k, char * out)
{
for(int i=0;i<=k;i++)
cout<<out[i]<<" ";
cout<<endl;
}
void Show(int p, int n, char *d, char *out,int k)
{
for(int i=p;i<n;i++)
{
out[k] = d[i]; OnPaint(k,out);
Show( i+1,n,d,out,k+1);
}
}
void ShowAllChildSet(int n, char * d)
{
char *out = new char
;
Show(0,n,d,out,0);
delete [] out;
}
int main()
{
/* int n=10;
int *x =new int
;
NQueens( n,x);
*/
/* int n =5;
int W[10] = {7,24,11,13,7};
int *out = new int
;
Sum(0, n, W,out,0,31,0);
*/
const int n=4;
char c
= {'a','b','c','d'};
char *d = &c[0];//{'a','b'};
ShowAllChildSet(n,d);
return 0;
}
好多问题都可能归结成当前子树的规模,DFS,就是对某一个节点的所有没有访问的子节点一个个访问,最后归结起来就能返回。
帖一些回溯的代码:下面的代码解决了三个问题:1:n皇后,2找出一个集合中所有满足某个条件的子集,3显示一个集合的所有子集。 注意变量数组的空间只需要一个就够了,因为是递归调用。
#include <iostream>
#include <cmath>
using namespace std;
int Num;
bool Place (int k, int i, int *x)
{
for(int j=0;j<k;j++)
if( (x[j]==i) || ( abs( x[j]-i)==abs(j-k) ) ) return false;
return true;
}
void NQueens(int k, int n, int *x)
{
for(int i=0; i<n;i++)
{
if( Place(k,i,x)) //»ØËÝ·¨£¬ÀûÓóÌÐò¾Íд³öËùÓпÉÄÜÐÔ£¬ÓÉÓÚÊǵ¥Ị̈߳¬ËùÒÔ»áÖ´ÐÐÍêÒ»¸öÔÙÖ´ÐÐÏÂÒ»¸ö£¬ËùÒÔ²»ÓÃ×Ô¼ºÐ´³ö»ØËÝ£¬ÎÒÒÔÇ°µ±³ÉÊ÷дÁË£¬¸´ÔÓµÄÌ«¶à
{ //²»ÐеĻ°£¬¾Í·ÅÆúÁËÒ»Ñù
x[k] = i;
if( k== n-1){
for(int m=0;m<n;m++)
cout << x[m]<<" ";
cout<<endl;
Num++;
}
else NQueens(k+1,n,x);
}
}
}
void NQueens(int n, int *x)
{
Num = 0;
NQueens(0,n,x);
cout<<Num<<endl;
}
int Get(int s, int wi,int D)
{
if( s + wi > D)
return 1;
else if( s + wi == D )
return 0;
return -1;
}
void Sum(int k, int n, int *x,int *out, int kk,int D, int s)
{ // ´ÓÔÊý×éµÚk¸ö¿ªÊ¼¼ÌÐøËÑË÷£¬ ÔÊý×én£¬*x
// *out kk ½á¹ûºÍ½á¹û½«Òª±£´æµÄϱê
// Ä¿±ê ºÍ ÏÖÔÚ״̬
for(int i=k; i<n;i++) // »ØËÝ·¨Ð§ÂÊÈçºÎ£¿
{
int tmp = Get( s, x[i],D);
if( tmp == 0 ) //ÏÔʾ³öÀ´
{
out[kk] = x[i];
for(int j=0;j<=kk;j++)
cout<<out[j]<<" ";
cout<<endl;
}
else if( tmp ==-1)
{
out[kk] = x[i];
if( i<n-1)
Sum(i+1,n,x,out,kk+1,D,s+x[i]); //Éî¶ÈÓÅÏÈ
}
else if( tmp ==1) //²»´¦Àí£¬Ï൱ÓÚ¼ôÈ¥ÁËÊ÷µÄÒ»¸öÖ§
{
}
}
}
void OnPaint(int k, char * out)
{
for(int i=0;i<=k;i++)
cout<<out[i]<<" ";
cout<<endl;
}
void Show(int p, int n, char *d, char *out,int k)
{
for(int i=p;i<n;i++)
{
out[k] = d[i]; OnPaint(k,out);
Show( i+1,n,d,out,k+1);
}
}
void ShowAllChildSet(int n, char * d)
{
char *out = new char
;
Show(0,n,d,out,0);
delete [] out;
}
int main()
{
/* int n=10;
int *x =new int
;
NQueens( n,x);
*/
/* int n =5;
int W[10] = {7,24,11,13,7};
int *out = new int
;
Sum(0, n, W,out,0,31,0);
*/
const int n=4;
char c
= {'a','b','c','d'};
char *d = &c[0];//{'a','b'};
ShowAllChildSet(n,d);
return 0;
}
相关文章推荐
- uva548 比较经典的知道两种遍历序列构造二叉树,注意后面的dfs的回溯
- UVA1600 Dfs回溯完全遍历+记忆化搜索(用最小距离剪枝)+细节处理 (值得复习)(水)
- poj 1321 棋盘问题 DFS+回溯 回溯学习
- hdu 1045 DFS+回溯
- HDU 1035Robot Motion(不带回溯的DFS)
- 用邻接表存储有向图并实现DFS(递归+非递归)BFS(非递归)两种遍历
- 第十二周 利用遍历思想求解图问题(DFS)
- DFS的遍历
- 递归,回溯,DFS,BFS的理解和模板
- HDU 1181 DFS回溯思想
- DFS 待遍历的元素被多次访问
- DFS 遍历数组所有可能存在的出栈顺序
- 邻接矩阵 遍历 DFS And BFS~~~
- 邻接表无向图的创建和遍历(dfs)
- 邻接矩阵无向图的创建和遍历(dfs)
- UVa 524 Prime Ring Problem(DFS , 回溯)
- Subsets and Subsets II (回溯,DFS,组合问题)
- 大话数据结构 code 第七章 04邻接表深度和广度遍历DFS_BFS
- uva 657 The die is cast(DFS遍历图)
- hdu 1045 贪心算法、DFS、枚举回溯&二分图