萌新の——迪杰特斯拉

迪杰特斯拉

#include<iostream>
#include<queue>
using namespace std;
const int maxn = 1e5+10;
const int INF = 1e9;
struct edge{
	int from,to,value;  //起点,终点,权值
	edge(int a,int b,int c){
		from =a;
		to= b;
		value = c;
	}
};

vector<edge>  e[maxn]; //邻接表
int pre[maxn];
struct s_node{    
	int id,dis;  // 结点,起点到id的最小距离
	s_node(int a,int b){
		id= a;
		dis=b;
	}
	bool operator < (const s_node &a) const
	{  return dis>a.dis;}
};
int n,m; //n点 m边
void dijkstra(int s){ // 求两点权值最小 
	bool done[maxn]; // 标记
	int dis[maxn];   // s到i的最小距离
	for(int i=0;i<=n;i++){
		dis[i] = INF;  
		done[i] =false;
	}
	dis[s] = 0;
	s_node  u(s,0);
	//u.id=s; u.dis =0;
	priority_queue<s_node> Q;
	Q.push(u);
    while(!Q.empty()){   
    	u = Q.top();                 // u ....s_ndoe
	    Q.pop();
	    if(done[u.id]) continue;
	    done[u.id]=true;
	    for(int i=0;i<e[u.id].size();i++){
	    	edge v=e[u.id][i];  //起点u.id ,邻接表 
			//cout<<v.from<<" "<<v.to<<" "<<v.value<<" ";
			//cout<<dis[v.to]<<" "<<dis[v.from]<<" "<<v.value<<endl; 
	    	if(done[v.to]) continue;  
	    	if(dis[v.to]>dis[v.from]+v.value){  //优先队列 刷新   
	    	  //cout<<"jindsa"<<v.to<<" "<<dis[v.to]<<endl;
	    		dis[v.to] = dis[v.from] + v.value;
	    		Q.push(s_node(v.to,dis[v.to]));
	    		pre[v.to] = pre[v.from];
			}
		}
	}
	for(int i=1;i<=n;i++)
	  printf("i:%d dis:%d\n",i,dis[i]);
	  cout<<endl;
}
int main (){
	  
	  scanf("%d %d",&n,&m);
	  while(m--){
	  	  int a,b,c;
	  	  scanf("%d %d %d",&a,&b,&c); //u->v 权值
	  	  e[a].push_back(edge(a,b,c));  //
	  	  //e[b].push_back(edge(b,a,c));
	  }
	  dijkstra(1);
	  return 0;
	  }

代码用优先队列和邻接表实现迪杰特斯拉算法。
优先队列: 从一个点出发,邻边寻找最小路径,主要用到的
思想: 已经知道3到8的权值为dis(3到8)40,在之前有一点9,
且dis(3到9)+dis(9到8)<dis(3到8) ,那么dis(3-8)刷新。
队列向后添加。
怎么才能很快的编出这样的代码呢?
画图理解。
其实就是广度搜索(BFS)。
从起点开始,邻边进队,

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

axtices

谢谢您的打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值