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