dijkstra求单源最短路径

//集合S:已计算出最短路径的集合
//集合V:未计算出最短路径的集合. 
//从集合V中选出最短路径的顶点,加入集合S中,并利用刚选的最短路径更新V中的最短路径。 
# include<iostream>
# include<cstring>
# include<stack>
using namespace std;
# define INF 0x3f3f3f3f
# define NIL -1
const int maxn=100+5;
struct node{
	int weight;  //权重 
};
struct graph{
	int virtexs[maxn];//顶点集 
	node virtex[maxn][maxn];   //邻接矩阵 
	int  virtexnum,edgenum; //顶点数,边数. 
};
stack<int> s;
graph g;
int dis[maxn];  //存储u到i的最短距离 ;
bool vis[maxn];
int predessor[maxn];//前趋数组例如predessor[v]=u表示v的前趋为u;  形成一个前趋树 
void init(graph &g)
{
	cin>>g.virtexnum>>g.edgenum;
	for(int i=0;i<g.virtexnum;i++)
	  cin>>g.virtexs[i];
	for(int i=0;i<g.virtexnum;i++)
	  {
	  	for(int j=0;j<g.virtexnum;j++)
	  	{
	  		if(i==j) g.virtex[i][j].weight=0;
		 else 
	  	    g.virtex[i][j].weight=INF;
	    }
	    predessor[i]=NIL;
	  }
	  for(int i=0;i<g.edgenum;i++)
	    {   int u,v,w;
	    	cin>>u>>v>>w;
	    	g.virtex[u-1][v-1].weight=w;
		}
}
void dijkstra(int u)//时间复杂度O(n*2); 
{
	memset(vis,0,sizeof(vis));
	for(int i=0;i<g.virtexnum;i++)
	  {
	  	  dis[i]=g.virtex[u-1][i].weight;  //初始化 
	  }
	  vis[u-1]=true;   //加入集合s中
	for(int j=1;j<g.virtexnum;j++)//
	{
			int min=INF,temp;

		for(int i=0;i<g.virtexnum;i++)  //从未计算 的最短路径中选择最小路径. 
			{
			if(!vis[i]&&min>dis[i])
		   		{
		   	  		min=dis[i];
		   	  		temp=i; 
				 	}  	
			}
			vis[temp]=true;   //加入集合s中
	 		for(int i=0;i<g.virtexnum;i++)  //进行比较,并更行dis数组 
	  		{
	  			if(!vis[i]&&dis[i]>dis[temp]+g.virtex[temp][i].weight)    
	  			 {
	  	 			dis[i]=dis[temp]+g.virtex[temp][i].weight;
	  	 			predessor[i]=temp;  //i的前趋为temp。
		   			}
	  			}
    }
}
/*void print_path(int n,int i)  //显式定义栈,并调用栈 
{
	    
	 s.push(i);
	int j=predessor[i];
	while(j!=-1)
	{
		s.push(j);
		j=predessor[j];
		}
		while(!s.empty())
		{
		cout<<"->"<<s.top()+1;
		s.pop();
		}
}*/

void print_path(int s,int v) //递归 
{
	if(s==v)
	{
		cout<<"->"<<s+1;
	}
	  else if(predessor[v]==NIL)  
	        {
	        	cout<<"->"<<v+1;   
			}
			else{
				print_path(s,predessor[v]);
				cout<<"->"<<v+1;
			} 
}
int main()
{
	int n;
	cin>>n;
	init(g);
	dijkstra(n);
	for(int i=0;i<g.virtexnum;i++)
	  {
	  	if((n-1)!=i)
 	  {    
 	        cout<<n;
	  		print_path(n,i);
			cout<<" ";
     		 if(dis[i]==INF)
	  		 	  cout<<"&"<<" ";
	    		else  
	  	  			 cout<<dis[i]<<" ";
	    		cout<<endl;
	 			}
	  }
	return 0;
}

总结:
(1)diskstra算法假定输入图中的所有边的权值非负.
(2) bfs是在无权图上执行的最短路径算法.
(4)bfs指出是否有从A到B的路径如果有,就可以找出最短路径.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值