单源最短路 Dijkstra

Dijkstra原理
构建图上的节点

struct node{
   int to;//终点
   int w;//权重
}

构造图

//假设n个顶点,m条边,源点为x;
struct node g[N];
for(int i=0;i<m;i++){
int s,e,w;
struct node edge;
cin>>s>>e>>w;
edge.to = e;
edge.w = w;
g[s].push_back(edge);
//二维的,g[s]为一个向量,向量中每个元素为一条从s出发的边,
}

求解单源最短路
初始化

int d[N] = {0};//d[i]表示源点s到点i的最短路径长度
for(int i=1;i<=n;i++){
   d[i] = Inf;  //初始化最短路径均为无穷大
}
d[x] =0;   //源点最短路径为0
for(int i=0;i<g[x].size();i++){//访问以x为源点的各边
    int to = g[x][i].to;  //从x为源点的边的终点序号
    int w = g[x][i].w;  
    d[to] = w;
}
int used[N]={0};
used[x] =1;

求解单源最短路

	int k = n;//n个顶点,循环n-1次。
    while(k--){
    	int minn = Inf;
    	int ind = -1;
    	for(int i=1;i<=n;i++){//求出离远点最近的点的索引
    		if(used[i]==0&&d[i]<minn){
    			minn =d[i];
    			ind = i;
			}
		}
		used[ind] =1;      //将已找到的离远点最近的标记位已访问。
		for(int i=0;i<vc[ind].size();i++){   //更新ind相连的边到源点的最短距离。
		     int  to = vc[ind][i].to;
		     int w = vc[ind][i].w;
			if(d[to]>(d[ind]+w)){
				d[to]=(d[ind]+w);
			}
		}
	}	

例题
poj3269

#include<iostream>
#include<algorithm>
#include<list>
#include<string.h>
#include<math.h>
#include<vector>
#include<stdio.h>
using namespace std;

#define N 1005
const int Inf =999999;
int n,m,x;
int total[N]={0};
struct path{
	int to;
	int len;
};

void dis(vector<path> vc[]){
	int used[N] ={0};
	int d[N]={0};
	for(int i=1;i<=n;i++){
		d[i]=Inf;
	}
		d[x] = 0;
		used[x] = 1;
	for(int i=0;i<vc[x].size();i++){	
		d[vc[x][i].to] = vc[x][i].len;
	}
	int k = n;
    while(k--){
    	int minn = Inf;
    	int ind = -1;
    	for(int i=1;i<=n;i++){
    		if(used[i]==0&&d[i]<minn){
    			minn =d[i];
    			ind = i;
			}
		}
		used[ind] =1;
		for(int i=0;i<vc[ind].size();i++){
			if(d[vc[ind][i].to]>(d[ind]+vc[ind][i].len)){
				d[vc[ind][i].to]=(d[ind]+vc[ind][i].len);
			}
		}
	}	
    for(int i=1;i<=n;i++){
    	total[i]+=d[i];
	}
}

int main()
{	
    
	cin>>n>>m>>x;
	vector<path> vc[N];
	vector<path> vc2[N];
	for(int i=0;i<m;i++){
		struct path p1,p2;
		int s,e,w;
		cin>>s>>e>>w;
		p1.to=e;
		p1.len=w;
		vc[s].push_back(p1);
		p2.to=s;
		p2.len=w;
		vc2[e].push_back(p2);
	}
	  int d1[N]={0};
	  dis(vc);
      dis(vc2);
      int maxx=-1;
      for(int i=1;i<=n;i++){
      	if(i!=x&&maxx<total[i]){
      		maxx = total[i];
		  }
	  }
      cout<<maxx<<endl;
    return 0;
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值