图论-最短路径 2.Dijkstra算法O (N2)

2. Dijkstra 算法 O (N 2 )
用来计算从 一个点到其他所有点的最短路径的算法 ,是一种 单源最短路径算法 。也就是说, 只能计算起点只有一个的情况
D ijkstra的时间复杂度是 O (N 2 ) ,它 不能处理存在负边权的情况
算法描述:
       设起点为 s dis[v] 表示从 s v 的最短路径, pre[v] v 的前驱节点,用来输出路径。
       a)初始化: dis[v]= (v s); dis[s]=0; pre[s]= 0 ;
       b) For (i = 1; i <= n ; i++)
            1. 在没有被访问过的点中找一个顶点 u 使得 dis[u] 是最小的。
            2.u 标记为已确定最短路径
            3.For u 相连的每个未确定最短路径的顶点 v
              if  ( dis[u]+w[u ][ v] < dis[v] )
               {
                  dis[v] = dis[u] + w[u ][ v];
                  pre[v] = u;
               }
        c)算法结束: dis[v] s v 的最短距离; pre[v] v 的前驱节点,用来输出路径。
 1 #include<cstdio>
 2 #include<cstring>
 3 #define N 1010
 4 #define MAXX 9999999
 5 int dis[N];
 6 int map[N][N];
 7 int qq[N];
 8 int que[N];
 9 int n,m,bein,s,ss;
10 int visit[N];
11 void work(int s)
12 {
13     visit[s]=1;
14     for(int k=1;k<=n;++k)
15     {
16         dis[k]=map[s][k];
17         if(map[s][k]!=MAXX)qq[k]=s;
18         else qq[k]=0;
19     }
20     visit[s]=1;
21     dis[s]=0;
22     for(int I=1;I<n;++I)
23     {
24         int k=s,minn=MAXX;
25         for(int j=1;j<=n;++j)
26         {        
27             if(!visit[j]&&dis[j]<minn)
28             {
29                 minn=dis[j];
30                 k=j;
31             }
32         }
33         visit[k]=1;
34         for(int i=1;i<=n;++i)
35         {
36             if(map[k][i]&&!visit[i]&&dis[i]>dis[k]+map[k][i])
37             {
38                 dis[i]=dis[k]+map[k][i];
39                 qq[i]=k;
40             }
41         }
42     }
43     printf("%d\n",dis[ss]);
44 }
45 void print (int u,int v    ) 
46 {
47     int tot=1;
48     que[tot]=v;
49     tot++;
50     int temp=qq[v];
51     while(temp!=u)
52       {    que[tot]=temp;
53         tot++;
54         temp=qq[temp];
55       }
56     que[tot]=u;
57     for(int i=tot;i>=1;i--)
58          if(i!=1)
59              printf("%d->",que[i]);
60          else
61              printf("%d",que[i]);
62 
63 }
64 int main()
65 {    
66     scanf("%d%d",&n,&m);
67     memset(dis,MAXX,sizeof(dis));
68     memset(map,MAXX,sizeof(map));
69     for(int i=1;i<=m;++i)
70     {
71         int x,y,q;
72         scanf("%d%d%d",&x,&y,&q);
73         map[x][y]=q;
74         map[y][x]=q;    
75     }
76     scanf("%d%d",&s,&ss);
77     work(s);
78     print(s,ss);
79     return 0;
80 }

 

转载于:https://www.cnblogs.com/mjtcn/p/6686148.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值