哈密尔顿算法求最短路径,超出范围

qq_35044454 2016-05-18 10:37:21

小白求大神帮忙看下
最多只能输入14个点,如果输入15个点不管边有多少条都会变成图二图三那样,不能再输入也没有任何输出结果。




测试数据:
请输入无向图的顶点数n,和其边数e,格式:n e

11 17

请输入边与边之间的关系,格式:顶点序号-权值-顶点序号
0 18 1
0 3 2
0 7 3
0 2 5
1 7 2
1 5 5
2 6 3
2 4 4
3 8 5
3 2 6
3 3 9
3 6 10
4 3 6
5 6 8
6 2 7
7 12 10
8 9 9




/********************此程序是用来进行中国邮路问题*******************/

/**********************欢迎使用*************************************/

#include <stdio.h>

#include <stdlib.h>
#include <iostream>
#include <windows.h>
#define Max 100

#define INF 6666
using namespace std ;
/********************邻接矩阵的结构体的定义******************/

typedef struct node

{ int cost[Max][Max]; //用来标记俩个顶点之间的权值
int edges[Max][Max]; //用来标记俩个顶点之间是否有边
}list,*MG;
int n=100;

int a[2000][2000]; //用来存储每次寻找到的哈密尔顿回路
/***********************无向图初始化函数*******************/

MG chushihua()

{

int s,i,j,e;
int weight;
MG p;
p=(MG)malloc(sizeof(list));

for(i=0;i<Max;i++)

for(j=0;j<Max;j++)

{

p->cost[i][j]=INF; //初始点的所有路径中各点到其他点的距离为无穷大
p->edges[i][j]=0; //初始化每2个顶点之间没有边

}

printf("\n请输入无向图的顶点数n,和其边数e,格式:n e \n\n");
scanf("%d %d",&n,&e);
printf("\n请输入边与边之间的关系,格式:顶点序号-权值-顶点序号\n"); //初始化矩阵

for(i=0;i<e;i++)
{
scanf("%d %d %d",&s,&weight,&j);

p->cost[s][j]=weight;

p->cost[j][s]=weight;

p->edges[s][j]=1; //当俩个顶点之间距离小于INf,则标记有边

p->edges[j][s]=1;

}

return p;

}

/***********************哈密尔顿回路寻找函数*******************/

int search(MG p)

{

int i,k=0,l=0; //l用来用来计回路总数
int *s=new int;//s用来标记是否遍历的顶点,b标记顶点标号
int *b=new int;
for(i=0;i<n;i++)

{
s[i]=0;
b[i]=-1; //对s[n],b[n]进行初始化

}

s[0]=1; //从0号开始遍历寻找
b[k]=0;

b[k+1]=b[k]+1; //顶点号累加
k++;
do //主循环
{
while(b[k]<n)

{

if(k==0)
{

s[b[k]]=1;

break;


}

else

if(s[b[k]]==0&&p->edges[b[k]][b[k-1]]==1) //当顶点未被遍历且与刚遍历的顶点之间有边,则退出当下循环

{

s[b[k]]=1;

break;

}


else b[k]++; //条件不满足,则顶点号累加继续寻找

}


if(b[k]>=n) //当顶点号大于N,则对回路数统计,输出
{

if(k==0)
{

printf("\n 图中所含回路个数为:");
printf("%d\n",l);
return l;

}


else //如果不满足前一个条件,则退回前一个顶点进行重新遍历
{
s[b[k-1]]=0;
b[k-1]=b[k-1]+1;
k--;
}


}

else if(k==n-1&&p->edges[b[k]][b[0]]!=1) //当最后一个顶点与起始顶点没有路径,则退回前一个顶点重新寻找

{
s[b[k-1]]=0;
b[k-1]=b[k-1]+1;
k--;
}

else

if(k==n-1&&p->edges[b[k]][b[0]]==1) //当寻找成功时,存储顶点,然后退回一步进行再遍历
{
for(i=0;i<n-1;i++)
{

a[l][i]=b[i];

}

a[l][i+1]=b[k];
l++;
s[b[k]]=0;
s[b[k-1]]=0;
b[k-1]=b[k-1]+1;
k--;
}

else //当顶点号不大于N,则继续按照之间思路进行寻找

{

i=0;

while(i<n &&(p->edges[b[k]][ i]==0||s[i]==1))

i++;

b[k+1]=i;

k++;

}

}while(1);

}

/**************************对遍寻的结果进行筛选,判断是否有哈密尔顿回路,如有求取最短回路************/

void shaixuan(int l,MG p)

{

int min[Max];
int sum=0;
int i,j,r;
int r1,r2;
if(l==0)

{
printf("\n 此无向图不存在哈密尔顿回路\n");

}
else

{
for(j=0;j<l;j++)


{

sum=0;
for(i=0;i<n-1;i++) //对回路求路径长
{
r1=a[j][i];
if(i==n-2)
{
r2=a[j][i+2];
}
else

{
r2=a[j][i+1];
}
printf("%d %d\n",r1,r2);
sum=sum+p->cost[r1][r2];
}
r2=a[j][n];
r1=a[j][0];
sum=sum+p->cost[r1][r2];
min[j]=sum; //存储路径长
}
sum=min[0];
r=0;
for(j=1;j<l;j++) //对路经长比较
if(min[j]<sum)
{
sum=min[j];
r=j;
}

printf("\n 无向图所有哈密尔顿回路如下:\n\n");
for(i=0;i<l;i++)

{

printf(" 哈密尔顿回路%d 路径长是%d\n\n",(i+1),min[i]);

printf(" 其经由的点为:");

for(j=0;j<n-1;j++)

printf("%d->",a[i][j]);

printf("%d\n",a[i][j+1]);

printf("\n");
}

printf("\n 此无向图的最短哈密尔顿回路路径长是%d\n",sum);

printf("\n 其经由的点为:");
for(j=0;j<n-1;j++)
printf("%d->",a[r][j]);
printf("%d\n",a[r][j+1]);

}

}

/*****************主函数*******************/
void main()

{
LARGE_INTEGER BegainTime ;
LARGE_INTEGER EndTime ;
LARGE_INTEGER Frequency ;
QueryPerformanceFrequency(&Frequency);

MG p;
int l;
printf(" ※※※※※※※此程序用于低于100个顶点以下的无向图寻找哈密尔顿回路※※※※※※※\n");
printf("\n 欢迎使用\n");
p=chushihua();
QueryPerformanceCounter(&BegainTime) ;
l=search(p);
shaixuan(l,p);
QueryPerformanceCounter(&EndTime) ;
printf("程序运行时间为:%ld\n",(EndTime.QuadPart - BegainTime.QuadPart )*1000 / Frequency.QuadPart) ;
}
...全文
518 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2016-05-19
  • 打赏
  • 举报
回复
代码功能归根结底不是别人帮自己看或讲解或注释出来的;而是被自己静下心来花足够长的时间和精力亲自动手单步或设断点或对执行到某步获得的中间结果显示或写到日志文件中一步一步分析出来的。 提醒:再牛×的老师也无法代替学生自己领悟和上厕所! 单步调试和设断点调试(VS IDE中编译连接通过以后,按F10或F11键单步执行,按Shift+F11退出当前函数;在某行按F9设断点后按F5执行停在该断点处。)是程序员必须掌握的技能之一。

64,648

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧