最短路径算法

供自己复习用

1、Floyd-Warshall算法

适用于多源最短路径,稠密图,和顶点关系密切,时间复杂度O(n^3)

思想是动态规划

核心代码:

for(int k=0;ke[i][k]+e[k][j])
				e[i][j]=e[i][k]+e[k][j];

思想是从两个点构成的路开始,不断往里面加点,首先确定增加1个点时的最短路径,再确定增加2个、3个...n个的情况。三重for循环其实是n个二重for循环的叠加,从代码上也可以直观地看出这种想法


2、Dijstra算法(重点)

单源最短路径,稠密图,和顶点关系密切,时间复杂度O((M+N)logN)

思想是贪心算法

核心代码:

/*pseudocode*/
void Dikjstra(){
	int v,w;//vertices
	int known[MaxVertexNum];
	int dist[MaxVertexNum];
	for(;;){
		v=smallest unknown distance vertex;
		if(v==NotAVertex)//defined to be -1
			break;
		known[v]=true;//means v is visited
		for(each w adjacent to v)
			if(!known[w])
				if(dist[v]+Cwv

贴几道PTA的题:

4-11 Shortest Path [1]   (25分)

Write a program to find the unweighted shortest distances from any vertex to a given source vertex in a digraph.

Format of functions:

void ShortestDist( LGraph Graph, int dist[], Vertex S );

where LGraph is defined as the following:

typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

The shortest distance from V to the source S is supposed to be stored in dist[V]. If V cannot be reached from S, store -1 instead.

Sample program of judge:

#include 
#include 

typedef enum {false, true} bool;
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */

typedef struct AdjVNode *PtrToAdjVNode; 
struct AdjVNode{
    Vertex AdjV;
    PtrToAdjVNode Next;
};

typedef struct Vnode{
    PtrToAdjVNode FirstEdge;
} AdjList[MaxVertexNum];

typedef struct GNode *PtrToGNode;
struct GNode{  
    int Nv;
    int Ne;
    AdjList G;
};
typedef PtrToGNode LGraph;

LGraph ReadG(); /* details omitted */

void ShortestDist( LGraph Graph, int dist[], Vertex S );

int main()
{
    int dist[MaxVertexNum];
    Vertex S, V;
    LGraph G = ReadG();

    scanf("%d", &S);
    ShortestDist( G, dist, S );

    for ( V=0; VNv; V++ )
        printf("%d ", dist[V]);

    return 0;
}

/* Your function will be put here */

Sample Input (for the graph shown in the figure):

7 9
0 1
0 5
0 6
5 3
2 1
2 6
6 4
4 5
6 5
2

Sample Output:

-1 1 0 3 2 2 1

这种没有权的最短路径问题可以用广度优先搜索,或者可以把它看成是边权重全部为1的最短路径问题。

PTA的作业是Shortest Path[3]、[4],没有代码,好好学习,杜绝抄袭。。。

譬如,下面是一种用广度优先的解法:

/* Your function will be put here */
void ShortestDist(LGraph Graph,int dist[],Vertex S){
	int queue[MaxVertexNum];
	int front=0,rear=0;
	Vertex v,w;
	int known[MaxVertexNum];
	int nv=Graph->Nv;
	PtrToAdjVNode helper;
	//initialize known[]
	for(int i=0;iG[S].FirstEdge;
	for(int i=0;iG[v].FirstEdge;
		while(helper){//对于每个邻接顶点
			if(dist[helper->AdjV]==-1){//因为用了广度优先搜索,可以保证每一步走的距离都是最小的,所以只有还未到达的情况才会去加1
				dist[helper->AdjV]=dist[v]+1;
				queue[rear++]=helper->AdjV;
			}
			helper=helper->Next;
		}
	}
}
下面这个题就是带权图了:

4-12 Shortest Path [2]   (25分)

Write a program to find the weighted shortest distances from any vertex to a given source vertex in a digraph. It is guaranteed that all the weights are positive.

Format of functions:

void ShortestDist( MGraph Graph, int dist[], Vertex S );

where MGraph is defined as the following:

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;
    int Ne;
    WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;

The shortest distance from V to the source S is supposed to be stored in dist[V]. If V cannot be reached from S, store -1 instead.

Sample program of judge:

#include 
#include 

typedef enum {false, true} bool;
#define INFINITY 1000000
#define MaxVertexNum 10  /* maximum number of vertices */
typedef int Vertex;      /* vertices are numbered from 0 to MaxVertexNum-1 */
typedef int WeightType;

typedef struct GNode *PtrToGNode;
struct GNode{
    int Nv;
    int Ne;
    WeightType G[MaxVertexNum][MaxVertexNum];
};
typedef PtrToGNode MGraph;

MGraph ReadG(); /* details omitted */

void ShortestDist( MGraph Graph, int dist[], Vertex S );

int main()
{
    int dist[MaxVertexNum];
    Vertex S, V;
    MGraph G = ReadG();

    scanf("%d", &S);
    ShortestDist( G, dist, S );

    for ( V=0; VNv; V++ )
        printf("%d ", dist[V]);

    return 0;
}

/* Your function will be put here */

Sample Input (for the graph shown in the figure):

7 9
0 1 1
0 5 1
0 6 1
5 3 1
2 1 2
2 6 3
6 4 4
4 5 5
6 5 12
2

Sample Output:

-1 2 0 13 7 12 3
解答:

/* Your function will be put here */
//注意:题目给的图使用邻接矩阵定义的
int FindMin(int dist[],int known[],int nv);
int FindMin(int dist[],int known[],int nv){
	int i,j,cnt=0;
	for(i=0;iNv;
	int known[MaxVertexNum];
	//initialize known[]
	for(int i=0;iG[v][i]>0){//vertices adjacent to v
				if(dist[i]>dist[v]+Graph->G[v][i])
					dist[i]=dist[v]+Graph->G[v][i];
			}
		}
	}
	for(int i=0;i

后面的[3]、[4]题就是在Dijkstra的基础上加一些逻辑。不贴了。

3、Bellman-Ford算法

待续

你可能感兴趣的:(数据结构与算法分析)