dijkstra算法c实现
❶ dijkstra算法的c实现
#include <stdlib.h>
#define INF 1000000000
#define MAXV 200
typedef struct Graph{
int n;
int w[MAXV][MAXV];
};
int d[MAXV];
int pre[MAXV];
void init_single_source(Graph *G,int s) {
for (int i=0;i<G->n;i++) {
d[i]=INF;
pre[i]=-1;
}
d[s]=0;
}
void relax(int u,int v,Graph *G) {
if (d[v]>d[u]+G->w[u][v]) {
d[v]=d[u]+G->w[u][v];
pre[v]=u;
}
}
int dijkstra(Graph *G,int s) {
init_single_source(G,s);
int S[MAXV],i,j,u,min;
for (i=0;i<G->n;i++) S[i]=0;
for (i=0;i<G->n;i++) {
min=INF;
u=-1;
for (j=0;j<G->n;j++) if (S[j]==0 && d[j]<min) {
u=j;
min=d[j];
}
S[u]=-1;
for (j=0;j<G->n;j++) if (S[j]==0) relax(u,j,G);
}
}
❷ Dijkstra算法的原理和C的编程实现
.Dijkstra算法求单源最短路径
语法:result=Dijkstra(Graph G,int n,int s,int t, int path[]);
参数:
G:
图,用邻接矩阵表示
n:
图的顶点个数
s:
开始节点
t:
目标节点
path[]:
用于返回由开始节点到目标节点的路径
返回值:
最短路径长度
注意:
输入的图的权必须非负
顶点标号从0开始
用如下方法打印路径:
i=t;
while (i!=s)
{
printf("%d<--",i+1);
i=path[i];
}
printf("%d\n",s+1);
源程序:
int Dijkstra(Graph G,int n,int s,int t, int path[])
{
int i,j,w,minc,d[max_vertexes],mark[max_vertexes];
for (i=0;i<n;i++) mark[i]=0;
for (i=0;i<n;i++)
{ d[i]=G[s][i];
path[i]=s; }
mark[s]=1;path[s]=0;d[s]=0;
for (i=1;i<n;i++)
{
minc=infinity;
w=0;
for (j=0;j<n;j++)
if ((mark[j]==0)&&(minc>=d[j])) {minc=d[j];w=j;}
mark[w]=1;
for (j=0;j<n;j++)
if ((mark[j]==0)&&(G[w][j]!=infinity)&&(d[j]>d[w]+G[w][j]))
{ d[j]=d[w]+G[w][j];
path[j]=w; }
}
return d[t];
}
原理:(1)初始时,S只包含源点,即S=,v的距离为0。U包含除v外的其他顶点,U中顶点u距离为边上的权(若v与u有边)或 ∞(若u不是v的出边邻接点)。 (2)从U中选取一个距离v最小的顶点k,把k,加入S中(该选定的距离就是v到k的最短路径长度)。 (3)以k为新考虑的中间点,修改U中各顶点的距离;若从源点v到顶点u(u U)的距离(经过顶点k)比原来距离(不经过顶点k)短,则修改顶点u的距离值,修改后的距离值为顶点k的距离加上边上的权。 (4)重复步骤(2)和(3)直到所有顶点都包含在S中。
❸ Dijkstra算法的c语言实现:文件读取、图的存储、算法实现、路径输出
要现写,你的分太少了,至少也200分吧,我给你个模板,时间复杂度为nLOG2(n):
dij邻接阵
#include <algorithm>
#include <deque>
#include <queue>
#include <iostream>
using namespace std;
#define MN 1001
#define INF (1<<29)
int graf[MN][MN];
struct node
{
int v;
int dis;
node(int vv,int dd){v=vv;dis=dd;}
node(){}
};
bool operator < (const node aa,const node bb)
{
return aa.dis>bb.dis;//最小堆
}
int dis[MN];
void dijkstra(int s,int n)//s是源点,[1..n]
{
node tmp;
int i,w;
for(i=1;i<=n;++i){dis[i]=INF;}
priority_queue < node,deque<node> > Q;
Q.push(node(s,0));
for(dis[s]=0;!Q.empty();)
{
tmp=Q.top();Q.pop();
if(tmp.dis!=dis[tmp.v])continue;
for(i=1;i<=n;++i)
{
w=graf[tmp.v][i];
if(w!=INF&&dis[tmp.v]+w<dis[i])
{
//必要时可保存路径pre[i]=tmp.v
dis[i]=dis[tmp.v]+w;
Q.push(node(i,dis[i]));
}
}
}
}
❹ 最短路径算法 Dijkstra 用C语言编出来
#include"iostream.h"
#include"stdlib.h"
#define MAXPOINT 3//定义最大的顶点数目
#define limit 32767 //设置没有路径的权代替无穷大
struct record{ //没个顶点的数据结构设置为一个数组队列
int number; //顶点号
int flag; //标志是否从队列中被选过如果为1表示选过为0表示未选
int allpath; //从源点到这个点的当前最短距离(权最小)
}path[MAXPOINT+1];
int cost[MAXPOINT+1][MAXPOINT+1]; //用来表示图的邻接矩阵
void main()
{int i,j,temp,front=1,rear=MAXPOINT,N,minnumber;
//temp表示在数组队列中的当前下标 front表示队列首 rear表示队列尾
//N 表示待输入的源点号码 minnumber 表示选中的点的号码
int min=32768; //设置一个初始值
for(i=1;i<=MAXPOINT;i++)
for(j=1;j<=MAXPOINT;j++)
{cout<<"请输入从第"<<i<<"点到第"<<j<<"点的路径长度(权)如果没有路径的话请输入'32767' "<<endl;
cin>>cost[i][j]; //初始化所有点之间的(权)路径值
}
//cout<<"请输入源点号"<<endl; //输入一个起点
//cin>>N;
for(N=MAXPOINT;N>=1;N--)//把每一个点轮流地都设置为起点,可以求出任意一对顶点之间的最短路径
{ for(i=front;i<=rear;i++) //初始化每个点的信息
{if(i==N)
path[i].allpath=0;
else
path[i].allpath=limit;
path[i].flag=0;
path[i].number=i;
}
while(rear>=1) //控制循环次数
{for(temp=front;temp<=MAXPOINT;temp++)
{ if(path[temp].allpath<min&&path[temp].flag==0)//选出一个具有最值
//的点
{ minnumber=path[temp].number;
min=path[temp].allpath ;
}
}
min=32768;
path[minnumber].flag=1;//把选中的点的标志变量置1表示已经被选过避免选中
for(i=1;i<=MAXPOINT;i++)//进行类似广度优先搜索,更新最短路径
{if((i!=minnumber)&&(path[minnumber].allpath+cost[minnumber][i]<path[i].allpath))
path[i].allpath=path[minnumber].allpath+cost[minnumber][i];
}
rear--;//次数减1
}
rear=MAXPOINT; //恢复数组以便于下一点的循环
for(j=1;j<=MAXPOINT;j++)
{ cout<<"第"<<N<<"点到第"<<j<<"点的最短路径长度(权)为";
cout<<path[j].allpath <<endl;
}
}
}
//这个程序可以求出任意一对顶点之间的最短路径,不过这种算法效率还不是很高,还有其他算法待续
❺ 求Dijkstra算法的C语言实现
//Dijkstra算法 C语言实现 2008-08-26 12:07 #include<stdio.h>
#include<stdlib.h> #define INFINITY 1000000000 //最大距离
#define MAX_NODES 1024 //最大节点数
int n,dist[MAX_NODES][MAX_NODES]; //dist[i][j]表示从 i 到 j 的距离 void shortest_path(int s, int t, int path[])
{
struct state
{
int predecessor; //前驱节点
int length; //到起始点的距离
enum {permanent, tentative} label;
}state[MAX_NODES];
int i,k,min;
struct state * p;
for(p=&state[0]; p<&state[n]; p++)
{
p->predecessor = -1;
p->length = INFINITY;
p->label = tentative;
}
state[t].length = 0;
state[t].label = permanent;
k = t; //k 是当前工作节点
do
{
for(i=0; i<n; i++)
{
if(dist[k][i]!=0 && state[i].label==tentative)
{
if(state[k].length+dist[k][i]<state[i].length)
{
state[i].length = state[k].length+dist[k][i];
state[i].predecessor = k;
}
}
}
k=0;
min=INFINITY;
for(i=0; i<n; i++)
{
if(state[i].label==tentative && state[i].length<min)
{
k=i;
min=state[i].length;
}
}
state[k].label = permanent;
}while(k!=s);
i=0;
k=s;
do
{
path[i++] = k;
k = state[k].predecessor;
}while(k>=0);
}
❻ Dijkstra 算法的C语言实现问题!!
type int Vertex;
struct TableEntry
{
List Header;
int Known;
DistType Dist;
Vertex Path;
}
#define NotAVertex (-1)
typedef struct TableEntry Table [Numvertex];
void InitTable( Vertex Start, Graph G, Table T )
{
int i;
ReadGraph( G,T );
for( i=0;i<NumVertex;i++)
{
T[i].Known = False;
T[i].Dist = Infinity
T[i].Path = NotAVertex
}
T[Start].Dist=0;
}
void PrintPath (Vertex V,Table T)
{
If(T[v].Path!=NotAVertex)
{
PrintPath(T[v].Path, T);
printf(" to");
}
printf("%v",V)
}
void Dijkstra(Table T)
{
Vertex V,W;
for(;;)
{
V = smallest unknow distance vertax;
if( V== NotAVertex)
break;
T[V].Known=True;
for each W adjacent to V
if(!T[w].known)
if(T[v].dist+cvw<T[w].Dist)
{
update w
decrease(t[w].dist to t[v].dist+cvw);
t[w].path=v;
count[w]=1
}
if(T[v].dist+cvw=T[w].Dist)
count[w]++;
}
}
❼ 求!最短路径算法 Dijkstra 用C语言编出来
Dijkstra算法--c++源代码--by
伟伟猪
[转贴
2005-12-15
20:21:00
]
发表者:
伟伟猪
/***********************************************
设G=(V,E)是一个每条边都有非负长度的有向图,有一个特异的顶点s称为缘。
单源最短路径问题,或者称为最短路径问题,是要确定从s到V中没一个其他
顶点的距离,这里从顶点s到x的距离定义为从s到x的最短路径问题。这个问题
可以用Dijkstra算法解决。下面我给我了c++下的源代码!
--by
伟伟猪
************************************************/
#include<iostream.h>
void
main()
{
int
infinity=100,j,i,n,k,t,**w,*s,*p,*d;
cout<<"input
the
value
of
n:";
cin>>n;
cout<<endl;
d=new
int[n];
s=new
int[n];
p=new
int[n];
w=new
int*[n];
for(i=0;i<n;i++)
{w[i]=new
int[n];}
for(i=0;i<n;i++)
for(j=0;j<n;j++)
cin>>w[i][j];
for(s[0]=1,i=1;i<n;i++)
{
s[i]=0;d[i]=w[0][i];
if(d[i]<infinity)
p[i]=0;
else
p[i]=-1;
}
for(i=1;i<n;i++)
{
t=infinity;k=1;
for(j=1;j<n;j++)
if((!s[j])&&(d[j]<t))
{t=d[j];k=j;}
s[k]=1;//point
k
join
the
S
for
(j=1;j<n;j++)
if((!s[j])&&(d[j]>d[k]+w[k][j]))
{d[j]=d[k]+w[k][j];p[j]=k;}
}
cout<<"从源点到其它顶点的最短距离依次如下:";
for(i=1;i<n;i++)
cout<<d[i]<<"
";
}
/*********
顶点个数用n表示,这里给出的例子n=6
100
1
12
100
100
100
100
100
9
3
100
100
100
100
100
100
5
100
100
100
4
100
13
15
100
100
100
100
100
4
100
100
100
100
100
100
具体例子见
电子工业出版社
《算法设计技巧与分析》148页
************/
❽ C语言实现Dijkstra算法
#include<stdlib.h> #define INFINITY 1000000000 //最大距离
#define MAX_NODES 1024 //最大节点数
int n,dist[MAX_NODES][MAX_NODES]; //dist[i][j]表示从 i 到 j 的距离 void shortest_path(int s, int t, int path[])
{
struct state
{
int predecessor; //前驱节点
int length; //到起始点的距离
enum {permanent, tentative} label;
}state[MAX_NODES];
int i,k,min;
struct state * p;
for(p=&state[0]; p<&state[n]; p++)
{
p->predecessor = -1;
p->length = INFINITY;
p->label = tentative;
}
state[t].length = 0;
state[t].label = permanent;
k = t; //k 是当前工作节点
do
{
for(i=0; i<n; i++)
{
if(dist[k][i]!=0 && state[i].label==tentative)
{
if(state[k].length+dist[k][i]<state[i].length)
{
state[i].length = state[k].length+dist[k][i];
state[i].predecessor = k;
}
}
}
k=0;
min=INFINITY;
for(i=0; i<n; i++)
{
if(state[i].label==tentative && state[i].length<min)
{
k=i;
min=state[i].length;
}
}
state[k].label = permanent;
}while(k!=s);
i=0;
k=s;
do
{
path[i++] = k;
k = state[k].predecessor;
}while(k>=0);
}
❾ 用dijkstra算法解决最短路径问题c语言代码实现时怎样将每一个路径的顶点次序依次输出出来
dijkstra算法原理主要就是已知源节点(v)和n个节点间代价函数(有向网络矩阵cost),通过不断将节点加入到一个节点子集S中,使得经过加入S后的各节点的路径代价是最小的,直至S节点包含了所有的n个节点停止。(具体算法阐明网上很多资料)。闲话少说,直接附程序吧~
/*
readme:
first,you need to input the node number, the cost matrix and the source node;
then the program will compute the best path.
finally,the program will output the lowest distance to the destination node, the pre-node and show the best path.
*/
#i nclude<stdio.h>
#i nclude <stdlib.h>
//Dijkstra算法实现函数
void Dijkstra(int n,int v,int dist[],int prev[],int **cost)
{
int i;
int j;
int maxint = 65535;//定义一个最大的数值,作为不相连的两个节点的代价权值
int *s ;//定义具有最短路径的节点子集s
s = (int *)malloc(sizeof(int) * n);
//初始化最小路径代价和前一跳节点值
for (i = 1; i <= n; i++)
{
dist[i] = cost[v][i];
s[i] = 0;
if (dist[i] == maxint)
{
prev[i] = 0;
}
else
{
prev[i] = v;
}
}
dist[v] = 0;
s[v] = 1;//源节点作为最初的s子集
for (i = 1; i < n; i++)
{
int temp = maxint;
int u = v;
//加入具有最小代价的邻居节点到s子集
for (j = 1; j <= n; j++)
{
if ((!s[j]) && (dist[j] < temp))
{
u = j;
temp = dist[j];
}
}
s[u] = 1;
//计算加入新的节点后,更新路径使得其产生代价最短
for (j = 1; j <= n; j++)
{
if ((!s[j]) && (cost[u][j] < maxint))
{
int newdist = dist[u] + cost[u][j];
if (newdist < dist[j])
{
dist[j] = newdist;
prev[j] = u;
}
}
}
}
}
//展示最佳路径函数
void ShowPath(int n,int v,int u,int *dist,int *prev)
{
int j = 0;
int w = u;
int count = 0;
int *way ;
way=(int *)malloc(sizeof(int)*(n+1));
//回溯路径
while (w != v)
{
count++;
way[count] = prev[w];
w = prev[w];
}
//输出路径
printf("the best path is:\n");
for (j = count; j >= 1; j--)
{
printf("%d -> ",way[j]);
}
printf("%d\n",u);
}
//主函数,主要做输入输出工作
void main()
{
int i,j,t;
int n,v,u;
int **cost;//代价矩阵
int *dist;//最短路径代价
int *prev;//前一跳节点空间
printf("please input the node number: ");
scanf("%d",&n);
printf("please input the cost status:\n");
cost=(int **)malloc(sizeof(int)*(n+1));
for (i = 1; i <= n; i++)
{
cost[i]=(int *)malloc(sizeof(int)*(n+1));
}
//输入代价矩阵
for (j = 1; j <= n; j++)
{
for (t = 1; t <= n; t++)
{
scanf("%d",&cost[j][t]);
}
}
dist = (int *)malloc(sizeof(int)*n);
prev = (int *)malloc(sizeof(int)*n);
printf("please input the source node: ");
scanf("%d",&v);
//调用dijkstra算法
Dijkstra(n, v, dist, prev, cost);
printf("*****************************\n");
printf("have confirm the best path\n");
printf("*****************************\n");
for(i = 1; i <= n ; i++)
{
if(i!=v)
{
printf("the distance cost from node %d to node %d is %d\n",v,i,dist[i]);
printf("the pre-node of node %d is node %d \n",i,prev[i]);
ShowPath(n,v,i, dist, prev);
}
}
}
❿ 用C或C++实现求最短路径的Dijkstra算法
/* 用邻接矩阵表示的图的Dijkstra算法的源程序*/
#include<stdio.h>
#define MAXVEX 100
typedef char VexType;
typedef float AdjType;
typedef struct
{ VexType vexs[MAXVEX]; /* 顶点信息 */
AdjType arcs[MAXVEX][MAXVEX]; /* 边信息 */
int n; /* 图的顶点个数 */
}GraphMatrix;
GraphMatrix graph;
typedef struct {
VexType vertex; /* 顶点信息 */
AdjType length; /* 最短路径长度 */
int prevex; /* 从v0到达vi(i=1,2,…n-1)的最短路径上vi的前趋顶点 */
}Path;
Path dist[6]; /* n为图中顶点个数*/
#define MAX 1e+8
void init(GraphMatrix* pgraph, Path dist[])
{
int i; dist[0].length=0; dist[0].prevex=0;
dist[0].vertex=pgraph->vexs[0];
pgraph->arcs[0][0]=1; /* 表示顶点v0在集合U中 */
for(i=1; i<pgraph->n; i++) /* 初始化集合V-U中顶点的距离值 */
{ dist[i].length=pgraph->arcs[0][i];
dist[i].vertex=pgraph->vexs[i];
if(dist[i].length!=MAX)
dist[i].prevex=0;
else dist[i].prevex= -1;
}
}
void dijkstra(GraphMatrix graph, Path dist[])
{ int i,j,minvex; AdjType min;
init(&graph,dist); /* 初始化,此时集合U中只有顶点v0*/
for(i=1; i<graph.n; i++)
{ min=MAX; minvex=0;
for(j=1; j<graph.n; j++)
if( (graph.arcs[j][j]==0) && (dist[j].length<min) ) /*在V-U中选出距离值最小顶点*/
{ min=dist[j].length; minvex=j; }
if(minvex==0) break; /* 从v0没有路径可以通往集合V-U中的顶点 */
graph.arcs[minvex][minvex]=1; /* 集合V-U中路径最小的顶点为minvex */
for(j=1; j<graph.n; j++) /* 调整集合V-U中的顶点的最短路径 */
{ if(graph.arcs[j][j]==1) continue;
if(dist[j].length>dist[minvex].length+graph.arcs[minvex][j])
{ dist[j].length=dist[minvex].length+graph.arcs[minvex][j];
dist[j].prevex=minvex;
}
}
}
}
void initgraph()
{
int i,j;
graph.n=6;
for(i=0;i<graph.n;i++)
for(j=0;j<graph.n;j++)
graph.arcs[i][j]=(i==j?0:MAX);
graph.arcs[0][1]=50;
graph.arcs[0][2]=10;
graph.arcs[1][2]=15;
graph.arcs[1][4]=5;
graph.arcs[2][0]=20;
graph.arcs[2][3]=15;
graph.arcs[3][1]=20;
graph.arcs[3][4]=35;
graph.arcs[4][3]=30;
graph.arcs[5][3]=3;
graph.arcs[0][4]=45;
}
int main()
{
int i;
initgraph();
dijkstra(graph,dist);
for(i=0;i<graph.n;i++)
printf("(%.0f %d)",dist[i].length,dist[i].prevex);
return 0;
}
}
}
}
void initgraph()
{
int i,j;
graph.n=6;
for(i=0;i<graph.n;i++)
for(j=0;j<graph.n;j++)
graph.arcs[i][j]=(i==j?0:MAX);
graph.arcs[0][1]=50;
graph.arcs[0][2]=10;
graph.arcs[1][2]=15;
graph.arcs[1][4]=5;
graph.arcs[2][0]=20;
graph.arcs[2][3]=15;
graph.arcs[3][1]=20;
graph.arcs[3][4]=35;
graph.arcs[4][3]=30;
graph.arcs[5][3]=3;
graph.arcs[0][4]=45;
}
int main()
{
int i;
initgraph();
dijkstra(graph,dist);
for(i=0;i<graph.n;i++)
printf("(%.0f %d)",dist[i].length,dist[i].prevex);
return 0;
}
这个稍作改动就可以了。