#include <iostream>
using namespace std;
typedef char VerTexType; //假设顶点的数据类型为字符型
typedef int ArcType;
#define MVNum 100 //最大顶点数
#define MaxInt 32767 //表示极大值,即∞
//----------------图的邻接矩阵---------------------
typedef struct{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
}AMGraph;
//辅助数组Edges的定义
struct{
VerTexType Head; //边的始点
VerTexType Tail; //边的终点
ArcType lowcost; //边上的权值
}Edge[(MVNum * (MVNum - 1)) / 2];
int Vexset[MVNum]; //辅助数组Vexset的定义
int LocateVex(AMGraph G , VerTexType v){
//确定点v在G中的位置
for(int i = 0; i < G.vexnum; ++i)
if(G.vexs[i] == v)
return i;
return -1;
}//LocateVex
void CreateUDN(AMGraph &G){
//采用邻接矩阵表示法,创建无向网G
int i , j , k;
cout <<"请输入总顶点数,总边数,以空格隔开:";
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
cout << endl;
cout << "输入点的名称,如a" << endl;
for(i = 0; i < G.vexnum; ++i){
cout << "请输入第" << (i+1) << "个点的名称:";
cin >> G.vexs[i]; //依次输入点的信息
}
cout << endl;
for(i = 0; i < G.vexnum; ++i) //初始化邻接矩阵,边的权值均置为极大值MaxInt
for(j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = MaxInt;
cout << "输入边依附的顶点及权值,如a b 6" << endl;
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
VerTexType v1 , v2;
ArcType w;
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
i = LocateVex(G, v1); j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
Edge[k].lowcost = w;
Edge[k].Head = v1;
Edge[k].Tail = v2;
}//for
}//CreateUDN
用图论解决一个问题:利用我给出的代码构造一个无向网,网中各结点除了有自身信息和指针域外,还有一个值,该值为工程量。要求用户再输入网中各节点的工程量,然后输入起点和所有边的总权值应大于的一个数。遍历无向图,当遍历过程中边的总权值大于了用户输入的那个数,停止遍历。经过多次遍历找出遍历过程中点的总工程量最小的那条路径并输出
在你代码基础上修改:两个步骤:
上结果:
上代码:
#include <iostream>
#include <climits>
using namespace std;
typedef char VerTexType; //假设顶点的数据类型为字符型
typedef int ArcType;
#define MVNum 100 //最大顶点数
#define MaxInt 32767 //表示极大值,即∞
//定义变量
int path_sum = 0; //记录路径总工程量
int min_path_sum = INT_MAX; //使用INT_MAX替代MAXINT //记录最小路径总工程量
int visit_vex[MVNum]; //记录已访问的节点
//图的邻接矩阵
typedef struct{
VerTexType vexs[MVNum]; //顶点表
ArcType arcs[MVNum][MVNum]; //邻接矩阵
int vexnum,arcnum; //图的当前点数和边数
int eng_amount[MVNum]; //节点工程量
}AMGraph;
//辅助数组Edges的定义
struct{
VerTexType Head; //边的始点
VerTexType Tail; //边的终点
ArcType lowcost; //边上的权值
}Edge[(MVNum * (MVNum - 1)) / 2];
int Vexset[MVNum]; //辅助数组Vexset的定义
int LocateVex(AMGraph G , VerTexType v){
//确定点v在G中的位置
for(int i = 0; i < G.vexnum; ++i)
if(G.vexs[i] == v)
return i;
return -1;
}//LocateVex
void CreateUDN(AMGraph &G){
//采用邻接矩阵表示法,创建无向网G
int i , j , k;
cout<<"请输入总顶点数,总边数,以空格隔开:";
cin >> G.vexnum >> G.arcnum; //输入总顶点数,总边数
cout << endl;
cout << "输入点的名称,如a" << endl;
for(i = 0; i < G.vexnum; ++i){
cout << "请输入第" << (i+1) << "个点的名称:";
cin >> G.vexs[i]; //依次输入点的信息
}
cout << endl;
//初始化邻接矩阵,边的权值均置为极大值MaxInt
for(i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = MaxInt;
cout << "输入边依附的顶点及权值,如a b 6" << endl;
for(k = 0; k < G.arcnum;++k){ //构造邻接矩阵
VerTexType v1 , v2;
ArcType w;
cout << "请输入第" << (k + 1)<<"条边依附的顶点及权值:";
cin >> v1 >> v2 >> w; //输入一条边依附的顶点及权值
i = LocateVex(G, v1);
j = LocateVex(G, v2); //确定v1和v2在G中的位置,即顶点数组的下标
G.arcs[i][j] = w; //边<v1, v2>的权值置为w
G.arcs[j][i] = G.arcs[i][j]; //置<v1, v2>的对称边<v2, v1>的权值为w
Edge[k].lowcost = w;
Edge[k].Head = v1;
Edge[k].Tail = v2;
}//for
}//CreateUDN
AMGraph G;
VerTexType start;
int sum_value;
//DFS遍历找最小路径
void DFS(int v) {
visit_vex[v] = 1;
path_sum += G.eng_amount[v]; //路径上节点工程量相加
//到达叶子节点或者边总权值大于输入值,比较当前路径总工程量
if(v == start || path_sum > sum_value) {
min_path_sum = min(min_path_sum, path_sum);
}
//递归遍历相邻节点
for(int w=0; w<G.vexnum; w++) {
if(visit_vex[w] == 0 && G.arcs[v][w] != INT_MAX && w != v) {
DFS(w);
}
}
path_sum -= G.eng_amount[v]; //回退,路径总工程量减去当前节点的工程量
visit_vex[v] = 0;
}
int main() {
CreateUDN(G); //构造无向网
//输入每个节点的工程量
cout << "输入每个节点的工程量:" << endl;
for(int i=0; i<G.vexnum; i++) {
cout << "请输入第" << i+1 << "个节点的工程量:";
cin >> G.eng_amount[i];
}
//输入起点和边总权值大于的数
VerTexType start;
cout << "请输入起点:";
cin >> start;
int sum_value;
cout << "请输入边总权值大于的数:";
cin >> sum_value;
for(int i=0; i<G.vexnum; i++) visit_vex[i] = 0;
DFS(LocateVex(G, start));
//从起点开始深度优先遍历
cout << "最小路径总工程量为:" << min_path_sum << endl;
}
#include <iostream>
#include <vector>
using namespace std;
typedef char VerTexType;
typedef int ArcType;
#define MVNum 100
#define MaxInt 32767
typedef struct {
VerTexType vexs[MVNum];
ArcType arcs[MVNum][MVNum];
int vexnum, arcnum;
} AMGraph;
struct Edge {
VerTexType Head;
VerTexType Tail;
ArcType lowcost;
};
int Vexset[MVNum];
int LocateVex(AMGraph G, VerTexType v) {
for (int i = 0; i < G.vexnum; ++i)
if (G.vexs[i] == v)
return i;
return -1;
}
void CreateUDN(AMGraph& G) {
int i, j, k;
cout << "请输入总顶点数,总边数,以空格隔开:";
cin >> G.vexnum >> G.arcnum;
cout << endl;
cout << "输入点的名称,如a" << endl;
for (i = 0; i < G.vexnum; ++i) {
cout << "请输入第" << (i + 1) << "个点的名称:";
cin >> G.vexs[i];
}
cout << endl;
for (i = 0; i < G.vexnum; ++i)
for (j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = MaxInt;
cout << "输入边依附的顶点及权值,如a b 6" << endl;
for (k = 0; k < G.arcnum; ++k) {
VerTexType v1, v2;
ArcType w;
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
cin >> v1 >> v2 >> w;
i = LocateVex(G, v1); j = LocateVex(G, v2);
G.arcs[i][j] = w;
G.arcs[j][i] = G.arcs[i][j];
Edge[k].lowcost = w;
Edge[k].Head = v1;
Edge[k].Tail = v2;
}
}
void DFS(AMGraph G, int start, ArcType limit, vector<VerTexType>& path, ArcType& minCost, vector<VerTexType>& minPath) {
path.push_back(G.vexs[start]);
if (limit <= 0 || path.size() >= G.vexnum) {
if (limit <= 0 && minCost > 0 && path.size() == G.vexnum) {
minCost = limit;
minPath = path;
}
return;
}
for (int i = 0; i < G.vexnum; ++i) {
if (G.arcs[start][i] != MaxInt && find(path.begin(), path.end(), G.vexs[i]) == path.end()) {
ArcType newLimit = limit - G.arcs[start][i];
if (newLimit > 0 && (minCost <= 0 || newLimit < minCost)) {
DFS(G, i, newLimit, path, minCost, minPath);
}
}
}
path.pop_back();
}
void findMinCostPath(AMGraph G, ArcType limit) {
vector<VerTexType> path;
vector<VerTexType> minPath;
ArcType minCost = -1;
for (int i = 0; i < G.vexnum; ++i) {
DFS(G, i, limit, path, minCost, minPath);
}
if (minCost > 0) {
cout << "最小总工程量路径为:";
for (int i = 0; i < minPath.size(); ++i) {
cout << minPath[i];
if (i != minPath.size() - 1)
cout << " -> ";
}
cout << endl;
}
else {
cout << "找不到满足条件的路径" << endl;
}
}
int main() {
AMGraph graph;
CreateUDN(graph);
ArcType limit;
cout << "请输入边的总权值应大于的一个数:";
cin >> limit;
findMinCostPath(graph, limit);
return 0;
}
答案参考ChapGPT Plus . 希望对你有帮助
这段代码是用来创建一个无向网的邻接矩阵表示的数据结构,并且实现了一些辅助函数和结构体来辅助操作。
要解决你描述的问题,可以在代码中添加以下函数:
// 遍历无向图,找出遍历过程中点的总工程量最小的路径
void TraverseGraph(AMGraph G, int start, int targetWeight) {
int currentWeight = 0; // 当前遍历路径的权值总和
int minWeight = MaxInt; // 最小权值总和
vector<VerTexType> minPath; // 最小权值路径
vector<VerTexType> currentPath; // 当前遍历路径
// 初始化辅助数组Vexset
for (int i = 0; i < G.vexnum; ++i)
Vexset[i] = 0;
// 从起点开始遍历
TraverseDFS(G, start, targetWeight, currentWeight, minWeight, minPath, currentPath);
// 输出最小权值路径
if (minWeight < MaxInt) {
cout << "最小权值路径为:";
for (int i = 0; i < minPath.size(); ++i)
cout << minPath[i] << " ";
cout << endl;
cout << "总工程量为:" << minWeight << endl;
} else {
cout << "没有找到满足条件的路径" << endl;
}
}
// 深度优先搜索遍历图
void TraverseDFS(AMGraph G, int v, int targetWeight, int currentWeight, int &minWeight, vector<VerTexType> &minPath, vector<VerTexType> ¤tPath) {
currentPath.push_back(G.vexs[v]);
Vexset[v] = 1;
currentWeight += G.vexs[v].工程量; // 假设工程量的值保存在结点的成员变量"工程量"中
// 达到目标权值时更新最小权值路径和总工程量
if (currentWeight > targetWeight && currentWeight < minWeight) {
minWeight = currentWeight;
minPath = currentPath;
}
// 继续深度优先搜索
for (int i = 0; i < G.vexnum; ++i) {
if (G.arcs[v][i] < MaxInt && Vexset[i] == 0) {
TraverseDFS(G, i, targetWeight, currentWeight, minWeight, minPath, currentPath);
}
}
// 回溯,恢复状态
currentPath.pop_back();
Vexset[v] = 0;
currentWeight -= G.vexs[v].工程量;
}
然后,在主函数中调用这个函数来解决问题:
int main() {
AMGraph G;
CreateUDN(G);
int targetWeight;
cout << "请输入边的总权值应大于的一个数:";
cin >> targetWeight;
int start;
cout << "请输入起点:";
cin >> start;
TraverseGraph(G, start, targetWeight);
return 0;
}
这样,
用户就可以输入无向网的节点信息和工程量,并输入起点和总权值的阈值,程序会输出在遍历过程中点的总工程量最小的路径。
引用gpt回答 有帮助的采纳一下哟
#include <iostream>
using namespace std;
typedef char VerTexType;
typedef int ArcType;
#define MVNum 100
#define MaxInt 32767
typedef struct{
VerTexType vexs[MVNum];
ArcType arcs[MVNum][MVNum];
int vexnum,arcnum;
}AMGraph;
struct{
VerTexType Head;
VerTexType Tail;
ArcType lowcost;
}Edge[(MVNum * (MVNum - 1)) / 2];
int Vexset[MVNum];
int LocateVex(AMGraph G , VerTexType v){
//确定点v在G中的位置
for(int i = 0; i < G.vexnum; ++i)
if(G.vexs[i] == v)
return i;
return -1;
}
void CreateUDN(AMGraph &G){
//创建无向网G
int i , j , k;
cout << "请输入总顶点数,总边数,以空格隔开:";
cin >> G.vexnum >> G.arcnum;
cout << "输入点的名称,如a" << endl;
for(i = 0; i < G.vexnum; ++i){
cout << "请输入第" << (i+1) << "个点的名称:";
cin >> G.vexs[i];
}
for(i = 0; i < G.vexnum; ++i)
for(j = 0; j < G.vexnum; ++j)
G.arcs[i][j] = MaxInt;
cout << "输入边依附的顶点及权值,如a b 6" << endl;
for(k = 0; k < G.arcnum;++k){
VerTexType v1 , v2;
ArcType w;
cin >> v1 >> v2 >> w;
i = LocateVex(G, v1);
j = LocateVex(G, v2);
G.arcs[i][j] = w;
G.arcs[j][i] = G.arcs[i][j];
Edge[k].lowcost = w;
Edge[k].Head = v1;
Edge[k].Tail = v2;
}
}
int main(){
AMGraph G;
CreateUDN(G); //构造无向网G
int sum;
cout << "请输入边的总权值应大于的数:";
cin >> sum;
int min_sum = MaxInt; //最小路径总权值
int path[MVNum]; //记录最小路径
int cnt = 0; //记录路径中已有的点数
cout << "请输入起点:";
VerTexType start;
cin >> start;
int v = LocateVex(G, start); //确定起点在G中的位置
path[cnt++] = v; //将起点加入路径
int total = G.vexs[v].value; //路径总权值初始化为起点权值
bool *visited = new bool[G.vexnum]; //创建访问标记数组
for(int i = 0; i < G.vexnum; i++)
visited[i] = false;
visited[v] = true; //标记起点已访问
while(cnt < G.vexnum){
int j;
for(j = 0; j < G.vexnum; j++) //从起点出发,找第一个邻接未访问顶点
if(G.arcs[v][j] != MaxInt && !visited[j])
break;
if(j == G.vexnum) break; //若找不到,则跳出循环
v = j; //转到第一个邻接未访问顶点
visited[v] = true; //标记该顶点已访问
total += G.vexs[v].value; //路径总权值增加该顶点权值
path[cnt++] = v; //将该顶点加入路径
if(total > sum) break; //当路径总权值大于输入值sum时,跳出循环
}
if(total < min_sum ){ //比较当前路径与最短路径总权值
min_sum = total;
for(int i=0; i<cnt; i++) //记录最短路径的顶点
cout << G.vexs[path[i]] << " ";
}
cout << endl;
delete []visited;
}
这段代码实现了一个邻接矩阵存储的无向网的创建,下面按照注释,简要介绍一下每一个函数的实现:
typedef char VerTexType
:定义了顶点的数据类型为字符型,即每个顶点用一个字符来表示。
typedef int ArcType
:定义了边的权值类型为整型。
#define MVNum 100
:定义了最大顶点数为 100。
#define MaxInt 32767
:定义了一个极大值常量,用于初始化边的权重。
typedef struct {...} AMGraph
:定义了一个邻接矩阵表示的无向网,包含顶点表和邻接矩阵两个部分,其中 vexnum
表示当前图中的顶点数,arcnum
表示当前图中的边数。
struct {...} Edge[(MVNum * (MVNum - 1)) / 2]
:定义了辅助数组 Edge
,用于在 Prim 算法的实现过程中存储临时的边数据,后面介绍 Prim 算法时会用到。
int Vexset[MVNum]
:定义了辅助数组 Vexset
,用于在 Kruskal 算法的实现过程中辅助判断两个顶点是否处于同一个连通分量中,后面介绍 Kruskal 算法时会用到。
int LocateVex(AMGraph G, VerTexType v)
:该函数用于定位某一顶点在图中的位置,输入参数为图 G
和顶点名称 v
,返回值为整型位置下标。
void CreateUDN(AMGraph &G)
:该函数用于创建一个无向网图,首先输入总顶点数和总边数,然后依次输入每个顶点的名称和每条边的的起点、终点、权重,最后构造出相应的邻接矩阵。需要注意的是,该函数的建立方式与输入方式需要根据实际数据来定制,比如输入方式可以改为从文件中读取等。
参考下:
#include <iostream>
#include <vector>
using namespace std;
typedef char VerTexType; // 假设顶点的数据类型为字符型
typedef int ArcType;
#define MVNum 100 // 最大顶点数
#define MaxInt 32767 // 表示极大值,即∞
// ----------------- 图的邻接矩阵 -----------------
typedef struct {
VerTexType vexs[MVNum]; // 顶点表
ArcType arcs[MVNum][MVNum]; // 邻接矩阵
int vexnum, arcnum; // 图的当前点数和边数
} AMGraph;
// 辅助数组Edges的定义
struct {
VerTexType Head; // 边的始点
VerTexType Tail; // 边的终点
ArcType lowcost; // 边上的权值
} Edge[(MVNum * (MVNum - 1)) / 2];
int Vexset[MVNum]; // 辅助数组Vexset的定义
int LocateVex(AMGraph G, VerTexType v) {
// 确定点v在G中的位置
for (int i = 0; i < G.vexnum; ++i) {
if (G.vexs[i] == v) {
return i;
}
}
return -1;
}// LocateVex
void CreateUDN(AMGraph &G) {
// 采用邻接矩阵表示法,创建无向网G
int i, j, k;
cout << "请输入总顶点数,总边数,以空格隔开:";
cin >> G.vexnum >> G.arcnum; // 输入总顶点数,总边数
cout << endl;
cout << "输入点的名称,如a" << endl;
for (i = 0; i < G.vexnum; ++i) { // 输入点的信息
cout << "请输入第" << (i + 1) << "个点的名称:";
cin >> G.vexs[i];
}
cout << endl;
for (i = 0; i < G.vexnum; ++i) { // 初始化邻接矩阵,边的权值均置为极大值MaxInt
for (j = 0; j < G.vexnum; ++j) {
G.arcs[i][j] = MaxInt;
}
}
cout << "输入边依附的顶点及权值,如a b 6" << endl;
for (k = 0; k < G.arcnum; ++k) { // 构造邻接矩阵
VerTexType v1, v2;
ArcType w;
cout << "请输入第" << (k + 1) << "条边依附的顶点及权值:";
cin >> v1 >> v2 >> w; // 输入一条边依附的顶点及权值
int i = LocateVex(G, v1); int j = LocateVex(G, v2); // 确定v1和v2在G中的位置,即顶点数组的下标
G.arcs[i][j] = w; // 边<v1, v2>的权值置为w
G.arcs[j][i] = G.arcs[i][j];
}
}
void DFS(AMGraph G, VerTexType v, int cost) {
// 深度优先搜索遍历无向图G,返回路径总权值最小的路径上的顶点集合PathSet
static vector<VerTexType> PathSet; // PathSet为静态变量,用于存储路径上的顶点集合
static vector<int> CostSet; // CostSet为静态变量,用于存储路径上的权值之和
static bool visited[MVNum] = { false }; // visited数组用于记录每个顶点是否被访问过
visited[v] = true; // 将当前顶点标记为已访问过
#如有帮助,恭请采纳