• Dijkstra算法 计算有向图的最短路径


    自然语言描述

    1. 定义三个数组,分别为

      V:表示所有的顶点集
      
      D:表示从起始点到其他各点的距离
      
      S:为已求得的从源点出发的最短路径长度的顶点的集合
      
    2. 设v0为起始点,若与v0直接连接的vi,则记录其权值到D[i],否则记录∞到D[i];

    3. 循环下列语句直至V-S为空集:

    (1)遍历D中的数据,若D[i]为最小值;记录vi到S中

    (2)更新D中的数据(遍历vj∈(V-S), D[ j ] = MIN(D[ j ] , D[ i ] + D[vi到vj的距离] ));

    伪代码

    算法:Dijkstra(G,v)v是起始点
     输入:G=(V,E)是带权连通图
     输出:D是含有起始点v到各点最短距离的数组
     过程:
     #define INF 0x7f7f7f7f
     S ← { }
     for i ←1 to |V| :
     	D[i] = INF
     for every vi in V except v:
     	D[i] = min{ 所有的E(v , vi)};
     while(|V-S| != 0){
     	//遍历D中数据
     	vk = min{every D[i] in D};
     	S ← v[k]
     	//更新D中数据
     	for every D[i] in D:
     	D[i] = min{D[i], D[k] + E(k,i) };
    }
     输出D
    

    问题

    Problem

    Given a directed graph, compute all the shortest paths from the source to other vertices.

    Input

    The first line is the number of test cases.

    For every test case, the first line is the number of node n, meaning nodes are 1,2,…,n.

    The next line is the number of edges m, then m lines are followed, where each line is in the form of u v w, meaning (u,v) is an edge and it has weight w (>0).

    The last line is the source vertex.

    Output

    For each test case, print all the shortest paths from the source s to other vertices (if the shortest path is finite) in the order of vertices in the following form (no spaces between):

    s-1:d1

    s-2:d2

    Sample Input

    2
    2
    1
    1 2 5
    1
    5
    6
    1 2 4
    1 3 6
    2 3 1
    4 5 1
    3 1 1
    5 4 2
    2
    

    Sample Output

    1-1:0
    1-2:5
    2-1:2
    2-2:0
    2-3:1
    

    代码实现

    #include <stdio.h>
    #define INF 0x7f7f7f7f
    #define SIZE 100 
    void Dijkstra(int matrix[][SIZE],int vertex, int dis[],int startingpoint);
    int min(int a, int b)return a>b?b:a;
    int  mindis(int dis[],int vertex,int usedvertex[]);
    int main(){
    	int times; //次数
    	scanf("%d",&times);
    	for(int t = 0; t < times; t++){
    		int vertex = 0; // 点数
    		int edge = 0; // 边数
    		scanf("%d",&vertex);
    		scanf("%d",&edge);
    		int matrix[SIZE][SIZE];
    		for(int i = 0; i <= vertex; i++){
    		 	for(int j = 0; j <= vertex; j++){
    		 		matrix[i][j] = INF;
    			 }
    		 }
    			//输入矩阵 
    		 for(int i = 0; i < edge; i++ ){
    		 	int x,y,weight;
    		 	scanf("%d",&x);
    		 	scanf("%d",&y);
    		 	scanf("%d",&weight);
    		 	if(weight < matrix[x][y]){
    		 		matrix[x][y] = weight;
    			 }
    		 }
    		 int startingpoint;
    		 scanf("%d",&startingpoint);
    		 //distance 数组
    		 int dis[vertex+1] ={0};
    		 for(int i = 1; i <= vertex; i ++){
    		 	dis[i] = matrix[startingpoint][i];
    		 } 
            
    		 //Dijkstra
    		 Dijkstra(matrix,vertex,dis,startingpoint); 
    		 //输出
    		 for(int i = 1; i <= vertex; i++){
    		 	if(dis[i]!=INF)printf("%d-%d:%d
    ",startingpoint,i,dis[i]);
    		 }
    	} 
    }
    //返回dis数组里的未被记录的最小值
    int  mindis(int dis[],int vertex,int usedvertex[]){
    	int min=INF, minvertex;
    	for(int i = 1 ; i <= vertex; i++){
    		if(usedvertex[i]==1)continue;
    		if(dis[i]<min){
    			min = dis[i];
    			minvertex = i;
    		}
    	}
    	return minvertex;
    }
    void Dijkstra(int matrix[][SIZE],int vertex, int dis[],int startingpoint){
    	int usedvertex[vertex+1] = {0}; //记录已确定最小值的点 
    	int count = vertex-1;
    	usedvertex[0] = 1;
    	usedvertex[startingpoint] = 1;
    	while(count !=0 ){
    		//第一步,取新的点 
    		int newvertex = mindis(dis,vertex,usedvertex);
    		usedvertex[newvertex] = 1;
    		//第二部,更新距离数组 
    		for(int i = 1; i <= vertex; i++){
    			dis[i] = min(dis[i],matrix[newvertex][i]+dis[newvertex]);
    		}
    		count --;
    	}
    	dis[startingpoint] = 0;
    }
    
    
  • 相关阅读:
    MySQL命名、设计及使用规范--------来自标点符的《MySQL命名、设计及使用规范》
    Mybatis 在 insert 之后想获取自增的主键 id
    MyBatis动态SQL foreach标签实现批量插入
    PowerDesigner设置表字段唯一约束
    Hadoop基本介绍
    oracle的行级触发器使用
    RFID-RC522、FM1702SL、M1卡初探
    PHP处理海量样本相似度聚类算法
    RFID(Radio Frequency Identification 射频识别)基本概念
    USB Keyboard Recorder
  • 原文地址:https://www.cnblogs.com/miaomiaolan/p/12915963.html
Copyright © 2020-2023  润新知