最短路问题:最短路问题是图论中最基础的问题,对于本菜鸟来说就不简单了,emmmmm....最短路是给定两个点为起点和终点的路径中,边的权值和最小路径。
1.单元最短路问题1(Bellman-Ford算法)
单元最短路问题是固定一个起点,求它到其他所有点的最短路问题。终点也固定问题叫做两点之间最短路问题。但是解决单元最短路问题的复杂度也是一样,因此通常当做单元最短路来求解。如果给定图是一个DAG(有向无环图)就可以利用拓扑序
![](https://i-blog.csdnimg.cn/blog_migrate/8ba2cdc82e976010c56b2a8b53cdd925.png)
给顶点编号,并利用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));
}
}
}
}
写的有点蒙了。