从最短路到差分约束系统

从最短路到差分约束系统

  1. Bellman-Ford(SPFA)

    1. void spfa(int s)
      {
               
      	memset(dis,-1,sizeof(dis));
      	memset(vis,0,sizeof(vis));
      	dis[s]=0;
      	q.push(s); vis[s]=1;
      	while(!q.empty())
      	{
               
      		int now=q.front(); vis[now]=0;
      		for(int i=head[now];i;i=nex[i])
      		{
               
      			if(dis[to[i]]==-1 || dis[to[i]]>dis[now]+val[i])
      			{
               
      				dis[to[i]]=dis[now]+val[i];
      				if(!vis[to[i]])
      				{
               
      					vis[to[i]]=1;
      					q.push(to[i]);
      				}
      			}
      		}
      	}
      }
      
    2. 注意复杂度为O(n*m),一般别用。

  2. Dijkstra

    1. void dijkstra(int s)
      {
               
      	for(int i=1;i<=n;i++)
      		dis[i]=-1,vis[i]=0;
      	dis[s]=0;
      	q.push(nod(s,0));
      	while(!q.empty())
      	{
               
      		int now=q.top().id;
      		q.pop();
      		if(vis[now]) continue;
      		vis[now]=1;
      		for(int i=head[now];i;i=nex[i])
      		{
               
      			if(dis[to[i]]==-1 || dis[to[i]]>dis[now]+val[i])
      			{
               
      				dis[to[i]]=dis[now]+val[i];
      				q.push(nod(to[i],dis[to[i]]));
      			}
      		}
      	}
      }
      
  3. Johnson

    1. 一般用于求N很大的多源最短路,复杂度为o(N * M * log(n)),边权可以为负。
    2. 做法:
      1. 我们新建一个虚拟节点0。从这个点向其他所有点连一条边权为 0 的边。
      2. 接下来用 Bellman-Ford 算法求出从 0 号点到其他所有点的最短路,记为 hi 。
      3. 对每一条边,我们将边权重新设置为 w+hu-hv 。
      4. 以每个点为起点,跑 n 轮 Dijkstra 即可。
  4. 差分约束系统

    1. 差分约束是什么呢,差分约束就是给定一些不等式,求是否存在合法解,
    2. 如一群小朋友分糖,要求小朋友a的糖必须比小朋友b的糖至少多d。
    3. 做法
      1. 那如果我们设小朋友a的糖为dis[a],小朋友b的糖为dis[b],那么就有等式dis[a]>=dis[b]+d,
      2. 那么说明dis[a]
      3. 当dis[a]=dis[b]+d,如果存在正环说明可以无限次松弛,则说明无解。
      4. 要求dis[a]==dis[b]+d 可以转换为dis[a]<=dis[b]+d && dis[a]>=dis[b]+d
      5. 要求dis[a]>dis[b]+d 可以转换为dis[a]>=dis[b]+d+1

你可能感兴趣的:(算法,dijkstra)