zoukankan      html  css  js  c++  java
  • Dijkstra算法 算法基础篇(三)

    View Code
      1 // Dijkstra算法.cpp : 定义控制台应用程序的入口点。
      2 //
      3 
      4 
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #define  NotAVertex (-1)
      8 #define  NumVertex 20
      9 #define  Infinity 1000
     10 typedef int Vertex;
     11 typedef int Arc;
     12 typedef int DistType;
     13 
     14 struct TableNode     //表节点
     15 {
     16     Vertex V;
     17     DistType Weigh;       //边重
     18     struct TableNode* NextArc;
     19 };
     20 
     21 typedef struct TableNode* EdgeNode;
     22 
     23 struct ListNode     //头节点
     24 {
     25     Vertex V;
     26     EdgeNode FirstArc;
     27     DistType Dist;
     28     int  Known;
     29     Vertex Path;
     30 };
     31 typedef struct ListNode* VexNode; //定义头节点指针
     32 
     33 
     34 struct Graphic                 //图的结构体 包括有边数,点数,头节点数组
     35 {
     36     Vertex VertexNum;
     37     Arc    ArcNum;
     38     struct ListNode Adj[NumVertex];
     39 };
     40 
     41 typedef struct Graphic* Graph;
     42 
     43 void ReadGraph(Graph G)             //图的输入函数
     44 {
     45     Vertex from,to;
     46     DistType weight;
     47     struct TableNode *S;
     48     printf("请输入节点数和边数,注意为整型!\n");
     49     scanf("%d%d",&(G->VertexNum),&(G->ArcNum));
     50     if(G->ArcNum<=0||G->VertexNum<=0)
     51     {
     52         printf("图边数或点数必须大于零\n");
     53         return;
     54     }
     55     for(int i =0;i<G->ArcNum;i++)
     56     {
     57         printf("请输入第%d条边的起点,终点和权值!\n",i+1);
     58         scanf("%d%d%d",&from,&to,&weight);
     59         S=(EdgeNode)malloc(sizeof(struct TableNode));
     60         S->V=to;
     61         S->Weigh=weight;
     62         S->NextArc=G->Adj[from].FirstArc;       //这里是from的头边给S的下一条边,这里是表节点插入细节,好好体会下。
     63         G->Adj[from].FirstArc=S;
     64     }
     65 
     66 }
     67 
     68 void InitNode(Graph G)                     //图的初始化
     69 {
     70     int i ;
     71     for(i=0;i<NumVertex;i++)
     72     {
     73         G->Adj[i].V=i;
     74         G->Adj[i].Path=NotAVertex;
     75         G->Adj[i].Known=false;
     76         G->Adj[i].Dist=Infinity;
     77         G->Adj[i].FirstArc=NULL;
     78     }
     79     ReadGraph(G);
     80     G->Adj[0].Dist=0;
     81 }
     82 
     83 Vertex ExtractMin(Graph G)                              //较为简单的寻找最小值函数,复杂度O(n),一直不是很满意
     84 {
     85     int i;int j=Infinity;
     86     Vertex Min=Infinity;
     87     for(i=0;i<G->VertexNum;i++)
     88     {
     89         if(!(G->Adj[i].Known)&&Min>G->Adj[i].Dist)//刚开始犯了一个很傻的错误,这里的第二个条件放到第一个循环了,总是不对。
     90         {
     91             Min=G->Adj[i].Dist;
     92             j=i;
     93         }
     94     }
     95     if(j==Infinity) return -1;
     96     return j;
     97 }
     98 
     99 void PrintPath(Graph G,Vertex V)             //打印分支函数,只能打印一条分支。
    100 {
    101     if(G->Adj[V].Path!=NotAVertex)
    102     {
    103         PrintPath(G,G->Adj[V].Path);
    104             printf("to");
    105     }
    106     printf("  %d  ",V);
    107 }
    108 
    109 
    110 
    111 void Dijkstra(Graph G)                      //函数::步步贪心,最终全体贪心
    112 {
    113     Vertex Value;
    114     EdgeNode pVex;
    115     for(int i=0;i<G->VertexNum;i++)
    116     {
    117         Value=ExtractMin(G);                     //抽取图中最小距离的点,纳入{S}
    118         if(Value==NotAVertex)
    119             break;
    120         G->Adj[Value].Known=true;
    121         pVex=G->Adj[Value].FirstArc;
    122     //    pEdge=pVex->NextArc;
    123         while(pVex!=NULL)                    //对图{Q-S}点的集合中与距离最小点毗邻的点做松弛操作
    124         {
    125             if(!(G->Adj[pVex->V].Known))     //邻接的节点更新
    126             {
    127                 if(G->Adj[Value].Dist+pVex->Weigh< G->Adj[pVex->V].Dist)
    128                 {
    129                     G->Adj[pVex->V].Dist=G->Adj[Value].Dist+pVex->Weigh;
    130                     G->Adj[pVex->V].Path=Value;
    131                 }
    132             }
    133             pVex=pVex->NextArc;
    134         }
    135     }
    136 }
    137 
    138 Vertex ReturnDistMax(Graph G) //这个函数是为了方便Print调用的,可以不要。
    139 {
    140     int i;
    141     Vertex key=0;
    142     DistType Max=0;
    143     for(i=0;i<G->VertexNum;i++)
    144         if(G->Adj[i].Dist>Max)
    145         {
    146             Max=G->Adj[i].Dist;
    147             key=i;
    148         }
    149         return key;
    150 
    151 
    152 }
    153 
    154 
    155 int _tmain(int argc, _TCHAR* argv[])
    156 {
    157     int i;
    158     Vertex V;
    159     Graph G=(Graph)malloc(sizeof(Graphic));
    160     InitNode(G);
    161     Dijkstra(G);
    162     printf("\n");
    163     for(i=0;i<G->VertexNum;i++)
    164     {
    165         printf("##  %d  ##",G->Adj[i].Dist);
    166 //        printf("##$  %d  $##",G->Adj[i].Path);
    167     }
    168 
    169     V=ReturnDistMax(G);
    170         
    171  //   PrintPath(G,V);
    172 
    173 
    174 
    175     return 0;
    176 }
  • 相关阅读:
    HDU 1501 Zipper(DFS)
    HDU 2181 哈密顿绕行世界问题(DFS)
    HDU 1254 推箱子(BFS)
    HDU 1045 Fire Net (DFS)
    HDU 2212 DFS
    HDU 1241Oil Deposits (DFS)
    HDU 1312 Red and Black (DFS)
    HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)
    HDU 1022 Train Problem I(栈)
    HDU 1008 u Calculate e
  • 原文地址:https://www.cnblogs.com/cslave/p/2548295.html
Copyright © 2011-2022 走看看