最短路问题

       最短路问题:最短路问题是图论中最基础的问题,对于本菜鸟来说就不简单了,emmmmm....最短路是给定两个点为起点和终点的路径中,边的权值和最小路径。

1.单元最短路问题1(Bellman-Ford算法)

单元最短路问题是固定一个起点,求它到其他所有点的最短路问题。终点也固定问题叫做两点之间最短路问题。但是解决单元最短路问题的复杂度也是一样,因此通常当做单元最短路来求解。如果给定图是一个DAG(有向无环图)就可以利用拓扑序

给顶点编号,并利用d[i]=min{d[j]+(从j到i的边的权值)|e=(j,i)属于E};.但是如果图中有圈,就无法依赖这样的顺序进行计算。在这种情况下,记当前到顶点i的最短路长度为d[i],并设初始d[s]=0,d[i]=INF,在不断使用这条递推关系更新d[i].就可以求出解。只要图中不存在负圈。这样更新操作就是有限的。结束之后d就是所求的最短距离了。

​
//从顶点from指向顶点to的权值cost的边 
struct edge{int from,to,cost;}; 
edge es[maxn];//边 

int d[maxn];//最短距离
int v,e;//v是定点数,e是边数
//求解从顶点s出发到所有点的最短距离 
void shortest_path(int s){
	for(int i=0;i<v;i++)d[i]=INF;
	d[s]=0;
	while(true){
		bool update=false;
		for(int i=0;i<e;i++){
			edge e=es[i];
			if(d[e.from]!=INF&&d[e.to]>d[e.from]+e.cost){
				d[e.to]=d[e.from]+e.cost;
				update=true;
			}
		}
		if(!update)break;
	}
} 
//检测是否有负圈 
bool find_negative(){
	memset(d,0,sizeof(d));
	
	for(int i=0;i<v;i++){
		for(int j=0;j<e;j++){
			edge e=es[i];
			if(d[e.to]>d[e.from]+e.cost){
				d[e.to]=d[e.from]+e.cost;
				//如果第n次仍然更新了,则存在负圈 
				if(i==v-1)return true;
			}
		}
	}
	return false;
} 

​

2.单元最短路问题二(Dijkstra算法)(不存在负边)

(1)找到最短距离已经确定的顶点,从它出发更新相邻顶点的最短距离。

(2)此后不需要再关心1中的“最短距离已经确定的顶点”。

int cost[maxn][maxn];//cost[u][v]表示e=(u,v)的权值(不存在这条边时设为INF); 
int d[maxn];//顶点s出发的最短距离 
bool used[maxn];//已经使用过的图 
int V;//顶点数 

//求从起点s出发到各个顶点的最短距离。 
void dijkstra(int s){
	fill(d,d+V,INF);
	fill(used,used+V,false);
	d[s]=0;
	
	while(true){
		int v=-1;
		//从尚未使用过的顶点中选择一个距离最小的顶点 
		for(int u=0;u<V;u++){
			if(!used[u]&&(v==-1||d[u]<d[v]))v=u;
		}
		if(v==-1)break;
		used[v]=true;
		for(int u=0;u<V;u++){
			d[u]=min(d[u],d[v]+cost[v][u]);
		}
	}
} 
struct edge{int to,cost};
typedef pair<int,int>P;//first是最短距离,second是顶点编号 

int V;
vector<edge>G[maxn];
int d[maxn];

void dijkstra(int s){
	//通过指定greater<P>参数,堆按照first从小到大的顺序取出值; 
	priority_queue<P,vector<P>,greater<P> >que;
	fill(d,d+V,INF);
	d[s]=0; 
	que.push(P(0,s)); 
	while(!que.empty()){
		P p=que.top();que.pop();
		int v=p.second;
		if(d[v]<p.first)continue;
		for(int i=0;i<G[v].size();i++){
			edge e = G[v][i];
			if(d[e.to]>d[v]+e.cost){
				d[e.to]=d[v]+e.cost;
				que.push(P(d[e.to],e.to));
			}
		}
	}	
}

写的有点蒙了。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值