64,648
社区成员
发帖
与我相关
我的任务
分享
/********************此程序是用来进行中国邮路问题*******************/
/**********************欢迎使用*************************************/
#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) ;
}