写一个c程序判断输入的图是否为哈密尔顿图

实验要求:

    写一个c程序判断输入的图是否为哈密尔顿图。

解题思路:

    首先,要解决的问题是如何把图转化为可以从键盘上输入的内容,并且可以让电脑“读懂”这个图。

    我采用的方式是:把每两个节点之前的关系都输进去,并用数组储存。

    具体实现方法:先输入节点的个数,和边的个数,目的是为了计算需要多少个scanf来读取键盘输入,然后再把每条边两边的节点输入进去,及时地用数组保存,因为做的这个程序是、无向的(也可以改成有向的),所以输入的时候调换两个节点的位置也是可行的(只需要输入两个节点存在关系就可以了)。

    其次,要解决的问题是如何去表示关系,比如1可以指向2,2也可以指向1,也就是1和2之前存在一条边,我采用的是a[x][++num[x]]=y;        a[y][++num[y]]=x;   用num数组给当前节点编号。方便后面遍历边的时候,可以有序不重复地进行。当然,储存关系的时候用链表更加直观、自然,但是用数组更加地顺手,所以就用数组来储存。

把所有对应的关系都输入到数组里面,该数组就构成了一颗树。树的顶点(根节点)不是固定的,因为把任意一个节点作为根节点,都有可能经历所有其他点,并且不重复走边,回到原点。

    接下来该问题就转化成为了如何走遍所有的节点,并回到原地。可以换句话说,就是寻找到最长的路径,并且回到原点,不重复走边。

    所以转化为DFS算法(深度优先搜索Depth-First-Search),意思是寻找树的最大深度路径。DFS算法没有具体的格式化的代码,它更多的是一种思想,通过对节点、路径的标记,来判断路有没有走过(防止被重复走过),通过递归来遍历所有的路径,并从中找到一条最长的路径。

    具体实现方法:

    从第一个节点开始,遍历所有的节点。

    每访问一个节点,调用一次Mydfs方法,并返回flag标记的值(flag为1代表找到了符合要求的路径,flag为0表示这不是哈密尔顿图)

再看Mydfs核心函数,首先这个函数要把main函数的x(遍历的开始位置),n(节点的个数),还有flag标记传入该函数。同时设定上一次访问的节点(为了避免走回头路,而且在最终判断是否构成哈密尔回路有很大的意义)

    Mark数组用来标记节点是否已经被访问,主要是为了在后面的代码中访问其他未访问的节点。每找到一个未标记的点,就把这个节点保存在output数组里面,其中通过length来记录节点具体保存在数组的哪一个位置。如果一条路已经到了尽头,但是无法构成哈密尔回路,那么length就要减一,并且把Mark数组清零,意思是返回到上一个节点,继续寻找该节点对应的没有被访问过的节点。如果还是没有找到这样的节点,那么再返回到上一个节点,以此类推,直到遍历所有的节点为止。该方法用递归来实现。

判断构成哈密尔顿图的条件:

1、下一个点为最初的起点(即回到原点)

2、下一条路是之前没有走过的路

3、路径的长度为n+1(包含了起点,重复计算)

 

 

核心代码:(如果想要完整版的代码请加QQ1228333410)

int Mydfs(int last,int i,int x,int n,intflag)//i表示当前访问节点,last表示上次访问的节点

{

         intj,s;

         Mark[i]=1;//标记为已经访问过

         output[++length]=i;//记录下答案

         for(j=1;j<=num[i];j++)

         {

                   if(!Mark[a[i][j]])//遍历与i相关联的所有未访问过的节点

                   {

                            flag=Mydfs(i,a[i][j],x,n,flag);

                   }

                   if(a[i][j]==x&&a[i][j]!=last&&length==n)//回到起点,构成哈密尔顿图

                   {

                            output[++length]=a[i][j];

                            flag=1;

                            length--;

                            break;

                   }

         }

         length--;

         Mark[i]=0;//回溯

         returnflag;

}

 

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
哈密尔顿是一种特殊的,其中存在一条包含每个顶点的路径。以下是使用 Java 编计算哈密尔顿的代码示例: ```java import java.util.*; public class HamiltonianGraph { private int[][] graph; private int[] path; private int numVertices; public HamiltonianGraph(int[][] graph) { this.graph = graph; this.numVertices = graph.length; this.path = new int[numVertices]; Arrays.fill(path, -1); } public boolean isHamiltonian() { path[0] = 0; return isHamiltonianUtil(1); } private boolean isHamiltonianUtil(int pos) { if (pos == numVertices) { return graph[path[pos-1]][path[0]] == 1; } for (int v = 1; v < numVertices; v++) { if (isSafe(v, pos)) { path[pos] = v; if (isHamiltonianUtil(pos+1)) { return true; } path[pos] = -1; } } return false; } private boolean isSafe(int v, int pos) { if (graph[path[pos-1]][v] == 0) { return false; } for (int i = 0; i < pos; i++) { if (path[i] == v) { return false; } } return true; } public static void main(String[] args) { int[][] graph = { {0, 1, 1, 0, 1}, {1, 0, 1, 1, 1}, {1, 1, 0, 1, 0}, {0, 1, 1, 0, 1}, {1, 1, 0, 1, 0} }; HamiltonianGraph hamiltonianGraph = new HamiltonianGraph(graph); if (hamiltonianGraph.isHamiltonian()) { System.out.println("Graph is Hamiltonian!"); } else { System.out.println("Graph is not Hamiltonian!"); } } } ``` 代码中,`HamiltonianGraph` 类表示一个哈密尔顿,其中的 `graph` 变量是一个二维数组,表示的邻接矩阵。`path` 变量是一个一维数组,表示当前求解的哈密尔顿路径。`numVertices` 变量表示中顶点的数量。 `isHamiltonian()` 方法用于检查是否是哈密尔顿。在 `isHamiltonianUtil()` 方法中,采用回溯算法来搜索哈密尔顿路径。`isSafe()` 方法用于检查从前一个顶点到当前顶点是否有一条边以及当前顶点是否已经出现过。 在 `main()` 方法中创建了一个示例,并检查它是否是哈密尔顿
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值