递归方法实现哈密顿回路问题Word文档格式.docx
《递归方法实现哈密顿回路问题Word文档格式.docx》由会员分享,可在线阅读,更多相关《递归方法实现哈密顿回路问题Word文档格式.docx(15页珍藏版)》请在冰豆网上搜索。
x=y;
y=t;
voidhamilton(intk)
if(k>
n&
&
c[x[k-1]][x[1]]==1)//一个解
output(x);
else
{
for(inti=k;
i++)
{
swap(x[k],x[i]);
if(c[x[k-1]][x[k]]==1)hamilton(k+1);
swap(x[i],x[k]);
}
}
intmain()
inti;
for(i=1;
i<
6;
++i)
x[i]=i;
output(x);
return0;
intn=5;
memset(c,0,sizeof(c));
c[1][2]=true;
c[2][1]=true;
c[1][4]=true;
c[4][1]=true;
c[2][4]=true;
c[4][2]=true;
c[2][3]=true;
c[3][2]=true;
c[3][5]=true;
c[5][3]=true;
c[4][5]=true;
c[5][4]=true;
c[2][5]=true;
c[5][2]=true;
c[3][4]=true;
c[4][3]=true;
for(inti=1;
=n;
i++)
x[i]=i;
//swap(x[1],x[5]);
hamilton
(2);
//默认以第一个城市开始,搜索解空间树(子集树形式)直接从第二层开始
cout<
endl;
//哈密顿回路问题回溯法,解空间树按子集树构造,
//采用迭代法实现
//起始结点(出发城市)默认以第一个开始
voidhamilton(intn,intx[],boolc[6][6])
inti,k;
bool*visited=newbool[n+1];
for(i=1;
x[i]=0;
visited[i]=false;
x[1]=1;
//默认以第一个城市开始
visited[x[1]]=1;
k=2;
//搜索解空间树(子集树形式)直接从第二层开始
while(k>
1)
x[k]++;
while(x[k]<
=n)
if(visited[x[k]]==0&
c[x[k-1]][x[k]]==1)//未到,有边
break;
if(x[k]<
=n&
k==n&
c[x[k]][x[1]]==1)//一个解
for(k=1;
k<
k++)
cout<
x[k]<
cout<
k--;
//break;
输出一个解结束时用他替代上两句
elseif(x[k]<
=n&
k<
n)//继续前行
visited[x[k]]=1;
k++;
else//不可行,回溯!
x[k]=0;
visited[x[k]]=0;
delete[]visited;
//五个城市!
boolc[6][6];
intx[6];
hamilton(5,x,c);
/***********************************/
stdio.h>
/*程序在此书写*/
stdlib.h>
math.h>
/*程序书写完毕*/
#ifdefDEBUG
start();
#endif
/*程序在此书写*/
intbase[]={1,5,10,20,50,100,200,500,1000,2000};
intk=sizeof(base)/sizeof(int);
/*0-9*/
unsignedlongintf[10][50001];
intx;
inti,j;
memset(f,0,sizeof(f));
for(i=0;
50001;
++i)
f[0][i]=1;
10;
f[i][0]=1;
for(j=1;
j<
++j)
if(j<
base[i])
f[i][j]=f[i-1][j];
else
f[i][j]=f[i][j-base[i]]+f[i-1][j];
char*p,*q,msg[5000],str[50],num[50];
while(gets(msg)!
=NULL&
strcmp(msg,"
0"
))
p=msg;
intcount=0;
while(sscanf(p,"
%s"
str)>
0)
count+=atoi(str);
p=strstr(p,str)+strlen(str);
if(count>
50000)
printf("
>
%d\n"
count);
else
%ld\n"
f[9][count]-1);
/*程序书写完毕*/
end(__FILE__);
/***********************************/迭代递归
inta[11];
/*intbase[]={0,1,5,10,20,50,100,200,500,1000,2000};
*/
intbase[]={0,2000,1000,500,200,100,50,20,10,5,1};
intk=sizeof(base)/sizeof(int)-1;
/*1-10*/
intx,m;
inti,j,s;
intlines=0;
char*p,*q,msg[5000],str[500],num[500];
intmaxnum=0;
lines=k;
memset(a,0,sizeof(a));
x=atoi(str);
a[lines]=x;
count+=x;
lines--;
/*printf("
continue;
ints[10];
intsp[10];
memset(s,0,sizeof(s));
introw=1;
sp[row]=-base[row];
s[0]=count;
s[1]=count;
longlongintl=0;
while(row>
sp[row]+=base[row];
if(base[row]==1&
s[row]>
sp[row])
sp[row]=s[row];
//printf("
%d-%d-%d\n"
row,s[row],sp[row]);
if(s[row]>
{
if(row<
k)
{
row++;
s[row]=s[row-1]-sp[row-1];
sp[row]=-base[row];
}
}
elseif(s[row]==sp[row])
++l;
row--;
row--;
printf("
%I64d\n"
l-1);
着色回溯递归
//输入n为顶点个数,颜色数m,图的邻接矩阵c[][]
//输出n个顶点的着色x[]
//递归方法求解
intm=3;
//颜色数
boolok(intk)//判断对顶点k着色以后是否合法着色
k;
if((c[k][i]==1&
x[k]==x[i]))
returnfalse;
returntrue;
voidbacktrack(intt)
if(t>
n)output(x);
for(inti=1;
=m;
i++){
x[t]=i;
if(ok(t))backtrack(t+1);
x[t]=0;
inti,j;
5;
for(j=1;
j++)
c[i][j]=false;
c[1][3]=true;
c[3][1]=true;
backtrack
(1);
着色回溯迭代
//第一个结点也可以有m种着色方案
voidm_coloring(intn,intm)
k=1;
=1)
=m)
if(ok(k)==1)break;
elsex[k]++;
=m&
k==n)//一个解
for(i=1;
"
"
//return;
如果只需要一个解可以将上两句去掉,加入返回语句
=m&
n)
else//回溯!
//memset
c[5][4]=true;
m_coloring(5,100);
return0;