图的最短路径-Dijkstra和Floyd


//Dijkstra.c
#include <stdio.h>
#include <stdlib.h>

/*--------------------------------------------------
*time:2016-04-17
*description: find the shortest path from the Vertex of sv to the Vertex of 4
*--------------------------------------------------*/ 


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define VNUM 5
#define MV 65536

int P[VNUM];
int Dist[VNUM];
int Mark[VNUM];
int Matrix[VNUM][VNUM] =
{
	{0,10,MV,30,100},
	{MV,0,50,MV,MV},
	{MV,MV,0,MV,10},
	{MV,MV,20,0,60},
	{MV,MV,MV,MV,0},
};

void Dijkstra(int sv)
{
	int i = 0;
	int j = 0;
	if((sv>=0)&&(sv<VNUM))
	{
		for(i=0;i<VNUM;i++)
		{
			Dist[i] = Matrix[sv][i];
			P[i] = sv;
			Mark[i] = 0;	
		}	
		Mark[sv] = 1;
		
		for(i=0;i<VNUM;i++)
		{
			int min = MV;
			int index = -1;
			
			for(j=0;j<VNUM;j++)
			{	
				if(!Mark[j]&&(Dist[j]<min))
				{
					min = Dist[j];
					index = j;	
				}		
			}	
			
			if(index>-1)
			{
				Mark[index] = 1;
			}
			printf("%d\n",index);
			for(j=0;j<VNUM;j++)
			{
				if(!Mark[j]&&(min+Matrix[index][j]<Dist[j]))
				{
					Dist[j] = min+Matrix[index][j];
					P[j] = index;	
				}	
			}
		}
		for(i=0;i<VNUM;i++)
		{
			int p = i;
			printf("(%d - > %d) :%d\n",sv,p,Dist[i]);
			do
			{
				printf("%d <- ",p);
				p = P[p];	
			}while(p!=sv);
			printf("%d\n",p);		
		}
	}
}

int main(int argc, char *argv[]) 
{
	int i = 0;
	Dijkstra(0);	
	return 0;
}

1
3
2
4
-1
(0 - > 0) :0
0 <- 0
(0 - > 1) :10
1 <- 0
(0 - > 2) :50
2 <- 3 <- 0
(0 - > 3) :30
3 <- 0
(0 - > 4) :60
4 <- 2 <- 3 <- 0

Dijkstra法主要是求从一点到其它点的最短路径。

如:从0到各个节点的最短路径


//Floyd.c
#include <stdio.h>
#include <stdlib.h>

/*--------------------------------------------------
*time:2016-04-17
*description: find the shortest path from the Vertex of sv to the Vertex of 4
*--------------------------------------------------*/ 


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define VNUM 5
#define MV 65536

int P[VNUM][VNUM]; 	//P[VNUM];
int A[VNUM][VNUM];	//Dist[VNUM];
int Matrix[VNUM][VNUM] =
{
	{0,10,MV,30,100},
	{MV,0,50,MV,MV},
	{MV,MV,0,MV,10},
	{MV,MV,20,0,60},
	{MV,MV,MV,MV,0},
};


void Floyd()
{
	int i = 0;
	int j = 0;
	int k = 0;
	for(i=0;i<VNUM;i++)
	{
		for(j=0;j<VNUM;j++)
		{
			A[i][j] = Matrix[i][j];
			P[i][j] = j;	
		}	
	}
	
	for(i=0;i<VNUM;i++)
	{
		for(j=0;j<VNUM;j++)
		{
			for(k=0;k<VNUM;k++)
			{
                if( (A[j][i] + A[i][k]) < A[j][k] )
                {
                    A[j][k] = A[j][i] + A[i][k];
                    P[j][k] = P[j][i];
                    printf("A[%d][%d] = A[%d][%d] + A[%d][%d]\n",j,k,j,i,i,k);
                }
			}	
		}	
	}
	for(i=0; i<VNUM; i++)
    {
        for(j=0; j<VNUM; j++)
        {
            int p = -1;
            
            printf("%d -> %d: %d\n", i, j, A[i][j]);
            
            printf("%d", i);
            
            p = i;
            
            do
            {
                p = P[p][j];
                
                printf(" -> %d", p);
            } while( p != j);
            
            printf("\n");
        }
    }
}
int main(int argc, char *argv[]) 
{
	printf("\n");
	printf("Floyd:\n");
	Floyd();
	return 0;
}

Floyd法是求各个点到各个点的最短路径。

Floyd:
0 -> 0: 0
0 -> 0
0 -> 1: 10
0 -> 1
0 -> 2: 50
0 -> 3 -> 2
0 -> 3: 30
0 -> 3
0 -> 4: 60
0 -> 3 -> 2 -> 4
1 -> 0: 65536
1 -> 0
1 -> 1: 0
1 -> 1
1 -> 2: 50
1 -> 2
1 -> 3: 65536
1 -> 3
1 -> 4: 60
1 -> 2 -> 4
2 -> 0: 65536
2 -> 0
2 -> 1: 65536
2 -> 1
2 -> 2: 0
2 -> 2
2 -> 3: 65536
2 -> 3
2 -> 4: 10
2 -> 4
3 -> 0: 65536
3 -> 0
3 -> 1: 65536
3 -> 1
3 -> 2: 20
3 -> 2
3 -> 3: 0
3 -> 3
3 -> 4: 30
3 -> 2 -> 4
4 -> 0: 65536
4 -> 0
4 -> 1: 65536
4 -> 1
4 -> 2: 65536
4 -> 2
4 -> 3: 65536
4 -> 3
4 -> 4: 0
4 -> 4




Process exited normally.
Press any key to continue . . .

Dijkstra法也可以实现:

//Dijkstra.c
#include <stdio.h>
#include <stdlib.h>

/*--------------------------------------------------
*time:2016-04-17
*description: find the shortest path from the Vertex of sv to the Vertex of 4
*--------------------------------------------------*/ 


/* run this program using the console pauser or add your own getch, system("pause") or input loop */

#define VNUM 5
#define MV 65536

int P[VNUM];
int Dist[VNUM];
int Mark[VNUM];
int Matrix[VNUM][VNUM] =
{
	{0,10,MV,30,100},
	{MV,0,50,MV,MV},
	{MV,MV,0,MV,10},
	{MV,MV,20,0,60},
	{MV,MV,MV,MV,0},
};

void Dijkstra(int sv)
{
	int i = 0;
	int j = 0;
	if((sv>=0)&&(sv<VNUM))
	{
		for(i=0;i<VNUM;i++)
		{
			Dist[i] = Matrix[sv][i];
			P[i] = sv;
			Mark[i] = 0;	
		}	
		Mark[sv] = 1;
		
		for(i=0;i<VNUM;i++)
		{
			int min = MV;
			int index = -1;
			
			for(j=0;j<VNUM;j++)
			{	
				if(!Mark[j]&&(Dist[j]<min))
				{
					min = Dist[j];
					index = j;	
				}		
			}	
			
			if(index>-1)
			{
				Mark[index] = 1;
			}
			//printf("%d\n",index);
			for(j=0;j<VNUM;j++)
			{
				if(!Mark[j]&&(min+Matrix[index][j]<Dist[j]))
				{
					Dist[j] = min+Matrix[index][j];
					P[j] = index;	
				}	
			}
		}
		for(i=0;i<VNUM;i++)
		{
			int p = i;
			printf("(%d - > %d) :%d\n",sv,p,Dist[i]);
			do
			{
				printf("%d <- ",p);
				p = P[p];	
			}while(p!=sv);
			printf("%d\n",p);		
		}
	}
}

int main(int argc, char *argv[]) 
{
	int i = 0;
	
	for(i=0;i<VNUM;i++)
	{
		printf("Dijkstra(%d):\n",i);
		Dijkstra(i);
		printf("\n");
	}	
	return 0;
}


Dijkstra(0):
(0 - > 0) :0
0 <- 0
(0 - > 1) :10
1 <- 0
(0 - > 2) :50
2 <- 3 <- 0
(0 - > 3) :30
3 <- 0
(0 - > 4) :60
4 <- 2 <- 3 <- 0


Dijkstra(1):
(1 - > 0) :65536
0 <- 1
(1 - > 1) :0
1 <- 1
(1 - > 2) :50
2 <- 1
(1 - > 3) :65536
3 <- 1
(1 - > 4) :60
4 <- 2 <- 1


Dijkstra(2):
(2 - > 0) :65536
0 <- 2
(2 - > 1) :65536
1 <- 2
(2 - > 2) :0
2 <- 2
(2 - > 3) :65536
3 <- 2
(2 - > 4) :10
4 <- 2


Dijkstra(3):
(3 - > 0) :65536
0 <- 3
(3 - > 1) :65536
1 <- 3
(3 - > 2) :20
2 <- 3
(3 - > 3) :0
3 <- 3
(3 - > 4) :30
4 <- 2 <- 3


Dijkstra(4):
(4 - > 0) :65536
0 <- 4
(4 - > 1) :65536
1 <- 4
(4 - > 2) :65536
2 <- 4
(4 - > 3) :65536
3 <- 4
(4 - > 4) :0
4 <- 4






Process exited normally.
Press any key to continue . . .

1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值