导航:首页 > 源码编译 > 最长路径算法代码实现c语言

最长路径算法代码实现c语言

发布时间:2023-01-25 22:01:59

1. 求如下有向图的关键路径以及任意两点之间的最短距离

用CPM算法求有向图的关键路径和用Dijkstra算法求有向图的最短路径的C语言程序如下

#include <stdio.h>

#include <malloc.h>

#include <stdlib.h>

#include <string.h>

#define MAX 20

#define INF 32767 // 此处修改最大值

#define nLENGTH(a) (sizeof(a)/sizeof(a[0]))

#define eLENGTH(a) (sizeof(a)/sizeof(char))/(sizeof(a[0])/sizeof(char))

typedef struct _graph{

char vexs[MAX]; // 顶点集合

int vexnum; // 顶点数

int edgnum; // 边数

int matrix[MAX][MAX]; // 邻接矩阵

}Graph, *PGraph;

// 边的结构体

typedef struct _EdgeData{

char start; // 边的起点

char end; // 边的终点

int weight; // 边的权重

}EData;

//指向节点的位置

int point_node(PGraph g,char c){

for(int i=0;i<g->vexnum;i++){

if(g->vexs[i]==c){

return i;

}

}

return -1;

}

PGraph create_graph(int b[][3],char a[],int n,int e){

char c1,c2; //边的2个顶点

PGraph g; //矩阵

g=(PGraph)malloc(sizeof(Graph));

//memset()第一个参数 是地址,第二个参数是开辟空间的初始值,第三个参数是开辟空间的大小

memset(g, 0, sizeof(Graph));

printf("顶点个数: ");//顶点数

g->vexnum=n;

printf("%d ",g->vexnum);

printf("边个数: ");//边数

g->edgnum=e;

printf("%d ",g->edgnum);

//初始化顶点

for(int j=0;j<g->vexnum;j++){

g->vexs[j]=a[j];

}

for(int i=0;i<g->edgnum;i++){

int p1,p2;

c1=char(b[i][0]);

c2=char(b[i][1]);

p1=point_node(g, c1);

p2=point_node(g, c2);

if (p1==-1 || p2==-1){

printf("input error: invalid edge! ");

free(g);

continue;

}

g->matrix[p1][p2]=b[i][2];

}

for(int i=0;i<g->vexnum;i++){

for(int j=0;j<g->vexnum;j++){

if(g->matrix[i][j]==0)

g->matrix[i][j]=INF;

}

}

return g;

}

//关键路径的最短时间

//关键路径法(Critical Path Method,CPM)

void CPM_road(PGraph g){

int i,j;

int a[MAX]={0},b[MAX]={-10};

int max=0;//最长路径

for( i=0;i<g->vexnum;i++){//列数遍历

for( j=0;j<g->vexnum;j++){//行数遍历

//如果g->matrix[j][i]大于0,说明此顶点有前顶点,由前边的遍历可知,前顶点的最长路径a[j],

//加上g->matrix[j][i]的路径就是当前a[i]的路径

if(g->matrix[j][i]!=INF && g->matrix[j][i]+a[j]>max){

max=g->matrix[j][i]+a[j];

a[i]=max;

}

}

max=0;

}

//显示最长路径

printf("第一个顶点到每一个顶点的最长路径:");

printf(" ");

for(i=0;i<g->vexnum;i++){

printf("V%d ",i+1);

}

printf(" ");

for(i=0;i<g->vexnum;i++){

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

}

printf(" ");

printf("最后一个顶点到每个顶点的最长路径:");

for( i=g->vexnum-1;i>=0;i--){ //列数遍历

for( j=g->vexnum-1;j>=0;j--){ //行数遍历

//如果g->matrix[j][i]大于0,说明此顶点有前顶点,由前边的遍历可知,前顶点的最长路径a[j],

//加上g->matrix[j][i]的路径就是当前a[i]的路径

if(g->matrix[i][j]!=INF && g->matrix[i][j]+b[j]>max){

max=g->matrix[i][j]+b[j];

b[i]=max;

}

}

max=0;

}

//显示最长路径

printf(" ");

for(i=0;i<g->vexnum;i++){

printf("V%d ",i+1);

}

printf(" ");

for(i=0;i<g->vexnum;i++){

printf("%d ",b[i]);

}

printf(" ");

printf("关键路径: ");

for(i=0;i<g->vexnum;i++){

if(a[i]==a[g->vexnum-1]-b[i]){

printf("V%c ",g->vexs[i]);

}

}

printf(" ");

}

void print_shortest_path(PGraph g,int* distance,int* path,int* used,int start,int end){

// 输出最短距离并打印最短路径

int i = 0, pre, inverse_path[g->vexnum];

char s1[3],s2[3];

sprintf(s1, "V%d", (start+1));

sprintf(s2, "V%d", (end+1));

printf("从%s顶点到%s顶点的最短距离: %d ", s1, s2, distance[end]);

inverse_path[i] = end;

pre = path[end];

if(pre == -1){

printf("没有通路! ");

}else{

while(pre != start){

inverse_path[++i] = pre;

pre = path[pre];

}

inverse_path[++i] = start;

printf("从%s顶点到%s顶点的最短路径: ", s1, s2);

for(; i > 0; i--){

sprintf(s1, "V%d", (inverse_path[i]+1));

printf("%s -> ", s1);

}

sprintf(s1, "V%d", (inverse_path[i]+1));

printf("%s ", s1);

}

return;

}

void shortest_path(PGraph g,int start, int end){ // 基于Dijkstra算法的最短路径函数

int distance[g->vexnum]; // 用于存放起始点到其余各点的最短距离

int path[g->vexnum]; // 用于存放起始点到其余各点最短路径的前一个顶点

int used[g->vexnum] = { 0 }; // 用于标记该顶点是否已经找到最短路径

int i, j, min_node, min_dis, pass_flag = 0;

for(i = 0; i < g->vexnum; i++){

distance[i] = g->matrix[start][i]; // 初始化距离数组

if(g->matrix[start][i] < INF){

path[i] = start; // 初始化路径数组

}else{

path[i] = -1;

}

}

used[start] = 1;

path[start] = start;

for(i = 0; i < g->vexnum; i++){

min_dis = INF;

for(j = 0; j < g->vexnum; j++){

if(used[j] == 0 && distance[j] < min_dis){

min_node = j;

min_dis = distance[j];

pass_flag++; // 标记是否存在通路

}

}

if(pass_flag != 0){

used[min_node] = 1;

for(j = 0; j < g->vexnum; j++){

if(used[j] == 0){

if(g->matrix[min_node][j] < INF && distance[min_node] + g->matrix[min_node][j] < distance[j]){

distance[j] = distance[min_node] + g->matrix[min_node][j];

path[j] = min_node;

}

}

}

}

}

print_shortest_path(g,distance, path, used, start, end);

return;

}

int main(){

int i,j;

PGraph gp;

char a[]={'1', '2', '3', '4', '5', '6', '7'};

int b[][3]={{'1', '2',3},

{'1', '3',2},

{'1', '4',6},

{'2', '4',2},

{'2', '5',4},

{'3', '4',1},

{'3', '6',3},

{'4', '5',1},

{'5', '7',3},

{'6', '7',4}};

int n=nLENGTH(a);

int e=eLENGTH(b);

gp=create_graph(b,a,n,e);

//打印邻接矩阵

printf("邻接矩阵: ");

for (i = 0; i < gp->vexnum; i++){

for (j = 0; j < gp->vexnum; j++)

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

printf(" ");

}

CPM_road(gp);

printf(" ");

for(i=0;i<gp->vexnum;i++){

for(j=0;j<gp->vexnum;j++){

if(i!=j)

shortest_path(gp,i, j);

}

}

return 0;

}


运行结果

2. 如何用迪杰斯特拉算法 在C语言上写一个 查找最长路径的程序

可以参考李春葆的数据结构,上面有类似的!

3. c语言运用邻接矩阵求最短路径中的最长路径问题

同问、

4. 编写c++算法求任意二叉树中一条最长的路径,并输出此路径上各结点的值

#include <stdio.h>
#define MaxSize 1000

typedef struct BiTNode {
int data;
struct BiTNode *lchild, *rchild;
}BiTNode,*BiTree;

void LongestPath(BiTree bt)//求二叉树中的第一条最长路径长度,并输出最长路径上的节点
{
BiTree p = bt, l[MaxSize], s[MaxSize]; //l, s是栈,元素是二叉树结点指针,l中保留当前最长路径中的结点
int i,top = 0, tag[MaxSize], longest = 0;
while (p || top >0)
{
while (p)
{
s[++top] = p;
tag[top] = 0;
p = p->lchild;
} //沿左分枝向下
if (tag[top] == 1) //当前结点的右分枝已遍历
{
if (!s[top]->lchild && !s[top]->rchild) //只有到叶子结点时,才查看路径长度
if (top>longest)
{
for (i = 1; i <= top; i++)
l[i] = s[i];
longest = top;
top--;
}//保留当前最长路径到l栈,记住最高栈顶指针,退栈
}
else if (top>0)
{
tag[top] = 1;
p = s[top]->rchild;
} //沿右子分枝向下
}//while(p!=null||top>0)
int k = 0;
for (k = 0; k < longest; k++)
{
printf("%d ", l[k]->data);
}
}//结束LongestPath

5. c语言编写路线

#include <stdio.h>
#include <malloc.h>
#include<stdlib.h>
#define MAX 100
#define MAXNUM 10000000
int previous[MAX-1];// 求路径需要
int pp[MAX-1];// 记录最短路径
typedef struct graphnode
{
int vexnum; //顶点
int arcnum; //弧
int gra[MAX][MAX]; //邻接矩阵表示0或1
}Graph;
int dist[MAX]; // 最短距离
int arc[MAX][MAX]; // 权

int main()
{
void Dijkstra(Graph *g,int v);
int i,j,n,m;
int v; //源点
Graph *G;
G=(Graph *)malloc(sizeof(Graph));
printf("vexnum:\n");
scanf("%d",&G->vexnum);
printf("arcnum:\n");
scanf("%d",&G->arcnum);
printf("graph:\n");
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
{
scanf("%d",&G->gra[i][j]);
}
for(i=0;i<G->vexnum;i++)
for(j=0;j<G->vexnum;j++)
{
if(G->gra[i][j]==1)
{
printf("请输入%d到%d的权值:",i,j);
scanf("%d",&arc[i][j]);//若有弧 则输入i到j直接的权
}
else
arc[i][j]=MAXNUM;
}
printf("请输入源点v的值:");
scanf("%d",&v);
Dijkstra(G,v);
printf("请输入源点所要到达的点:\n");
scanf("%d",&n);
pp[0]=0;
i=1;
m=n;// 记录n的值
while(n!=0)// 求0到其他点路径
{
pp[i]=previous[n];
i++;
n=previous[n];

}
printf("Path:0 -> ");
for(j=G->vexnum-1;j>=0;j--)
if(pp[j]!=0)
printf(" %d -> ",pp[j]);
printf("%d\n",m);
return 0;

}
void Dijkstra(Graph *G,int v)
{
int previous[MAX-1];
int newdist;
bool sign[MAX];
if(v<0||v>MAX-1)
{
printf("该源点不存在!\n");
return;
}

for(int i=0;i<G->vexnum;i++) //初始化
{
dist[i]=arc[v][i];
sign[i]=false;
if(dist[i]==MAXNUM)
previous[i]=0;
else
previous[i]=v;
}

dist[v]=0;
sign[v]=true;

for(i=0;i<G->vexnum;i++) // i<n-1 待定
{
float temp=MAXNUM;
int u=v; //u 中间变量
for(int j=0;j<G->vexnum;j++)
if((!sign[j])&&(dist[j]<temp))
{
u=j;
temp=dist[j];
}
sign[u]=true;
for(j=0;j<G->vexnum;j++)
if((!sign[j])&&(arc[u][j]<MAXNUM))
{
newdist=dist[u]+arc[u][j];
if(newdist<dist[j])
{
dist[j]=newdist;
previous[j]=u;
}

}
}
for(i=0;i<G->vexnum;i++)
if(dist[i]!=MAXNUM)
printf("从%d到%d的最短路径是 %d\n",v,i,dist[i]);
else
printf("从%d到%d无最短路径\n",v,i);
printf("\n");

}
这是Dijkstra算法求单源最短路径算法 上程序中 假定顶点从0开始,搜索整个图,然后求出0到其他各点的最短距离,存放在dist数组中,main函数后面几行是求0到其他各点的路径 基本上能满足你的要求了

6. 求帮算法作业!用动态规划法求解最长路径问题

先对图进行拓扑排序 一个结果为s b a c d t 拓扑排序的时候初始化dist[i] 表示从s到i的距离
dist[i]=max{dist[u]+edge[u][i], dist[i]}.
i从s取到t 最终得结果

7. 用C语言实现以下问题并讲解大概思路和所用算法,非常感谢!

唔,你这个问题的话,因为你这个不指定起点,所以应该是多源最长路径问题,我参考了一下多源最短路径的Floyd算法如下,不知道可不可以啊:
首先是输入
g[i][j]表示从i城市到j城市所需要的路费,

int g[M][M]={{null,2,1,null},{null,null,5,4},{null,null,null,null},{null,null,null,null}}
null表示两个城市之间不存在路径,看上去这个数组很浪费,因为Floyd算法是可以针对更复杂的图进行计算的算法,具体有没有更优算法我也不知道=。=
然后让M=你输入的城市数量-1,这里M=4
输入设置好以后,就可以进行循环比较了,通过三重循环的比较,最终得到D[4][4]这样一个数组,这个数组中的D[i][j]表示从i城市到j城市所需要的最高的路费,然后再通过比较数组D中最大值,应该就可以得出结果了。

这里复制一下原理:
Floyd-Warshall算法的原理是动态规划。
设Di,j,k为从i到j的只以(1..k)集合中的节点为中间节点的最短路径的长度。
若最短路径经过点k,则Di,j,k = Di,k,k − 1 + Dk,j,k − 1;
若最短路径不经过点k,则Di,j,k = Di,j,k − 1。
因此,Di,j,k = min(Di,k,k − 1 + Dk,j,k − 1,Di,j,k − 1)。(而我们是求最长,所以应该换成max就可以了)

void floyd(int g[M][M],int D[M][M])
{
for(int k = 0;k<M;k++)
for(int i = 0;i<M;i++)
{
for(int j = 0;j<M;j++)
{
if(k == 0)//k=0,第一轮循环时,先将基础值赋值给D数组
{
if(g[i][j]!=null)
D[i][j] =g[i][j];
else
{
g[i][j]=-30000;//在k=0的第一轮循环中,让没有路径的地方等于一个大的负数,这样之后的比较就不需要重复的判断非空了
D[i][j]=-30000;
}}

else//当k不等于0时,也就是第二轮循环之后,进行最长路径的比较和计算,大的值赋值给D数组
{
D[i][j] = MAX(D[i][j],D[i][k]+D[k][j]);
}

}
}
}
最后再写个循环,取出数组D中的最大值就可以得到最大路程了然后再算最大路费,如果前面的算法没错的话。
我的感觉的话,Floyd-Warshall算法比较容易实现,不需要特殊的数据结构,就是可能算法的时间和空间复杂度比较高,不知道你怎么看

8. 跪求最短(长)路径算法,(按要求的)Dijkstra算法C/C++源代码

int Locate(MGraph G,VexType v)
{
for(int i=0;i<G.vexnum;++i)
if(strcmp(v,G.vexs[i])==0)
return i;
return -1;
}
void ShortestPath(MGraph G,VexType v,int dist[],int path[])
{//求顶点v到其余各个顶点的最短路径长度,并存放在dist数组中,path数组存放路径
int S[MAX_VEX_NUM]={0};
int i,j,k;
for(i=0;i<G.vexnum;++i)
{
k=Locate(G,v);
dist[i]=G.arcs[k][i];//初始化数组dist
if(k!=i&&dist[i]<INFINITY)path[i]=k;
else path[i]=-1;//初始化数组path
}
S[k]=1;dist[k]=0;
for(i=1;i<G.vexnum;++i)//循环n-1次
{
int min=INFINITY;
int u=k;
for(j=0;j<G.vexnum;++j)
if(!S[j]&&dist[j]<min)
{u=j;min=dist[j];}
S[u]=1;
for(j=0;j<G.vexnum;++j)
if(!S[j]&&G.arcs[u][j]<INFINITY&&dist[u]+G.arcs[u][j]<dist[j])
{
dist[j]=dist[u]+G.arcs[u][j];
path[j]=u;
}
}
}
void Print(MGraph G,int dist[],int path[])
{
for(int i=1;i<G.vexnum;++i)
{
if(path[i]==-1)cout<<"v0到"<<G.vexs[i]<<"没有路径\n";
else
{
int stack[MAX_VEX_NUM],top=0,k;
stack[top++]=i;k=path[i];
while(k>=0)
{stack[top++]=k;k=path[k];}
while(--top>=0)
cout<<G.vexs[stack[top]]<<"->";
cout<<"最短路径长度="<<dist[i]<<endl;
}
}
}

9. 请高手帮忙修改,编写一个求有向无环图中最长路径的数据结构C语言版程序的题

把代码重新贴一下吧,

阅读全文

与最长路径算法代码实现c语言相关的资料

热点内容
单片机控制显示器 浏览:754
顶好花app下载怎么找不到 浏览:987
手机命令大全 浏览:806
怎么下邮政银行app 浏览:248
不背单词app单词怎么学习 浏览:479
程序员日常操作搞笑 浏览:380
android检查是否安装 浏览:373
苹果手机编辑pdf文件 浏览:458
android系统名字 浏览:969
安卓手机如何进去有求必应屋 浏览:432
指数除法运算法则底数不同 浏览:894
90压缩干粮09压缩干粮 浏览:516
android线程池框架 浏览:481
手机自带解压能解压哪些文件 浏览:804
linux安装hba驱动 浏览:119
java构造函数new 浏览:668
怎么查家里电器耗电量app 浏览:506
原神一直显示重新连接服务器怎么办 浏览:826
一般用途轴流式压缩机 浏览:926
没学历的怎么学编程 浏览:901