最短路

Floyd

变量

  • int n\texttt{int n}:图的节点数。
  • int a[i][j]\texttt{int a[i][j]}iijj 的最短路。

函数

  • void Floyd(int n,int *a)\texttt{void Floyd(int n,int *a)}:求最短路。

代码

void Floyd(int n,int *a){
	for(int k=1;k<=n;k++)
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
}

Dijkstra

变量

  • int d[i]\texttt{int d[i]}:点 ii 到源点的最短路长度。
  • int v[i]\texttt{int v[i]}:标记节点 ii 是否已经更新完全。

函数

  • void Dijkstra(int s)\texttt{void Dijkstra(int s)}:求以 ss 为源点的单源最短路。

代码

int d[N],v[N];
void Dijkstra(int s){
    memset(d,0x3f,sizeof(d));
    memset(v,0,sizeof(v));
    d[s]=0;
    priority_queue<pair<int,int> >q;
    q.push(make_pair(0,s));
    while(q.size()){
        int x=q.top().second;
        q.pop();
        if(v[x])
            continue;
        v[x]=1;
        for(int i=head[x];i;i=nxt[i]){
            int y=ver[i],z=edge[i];
            if(d[y]>d[x]+z){
                d[y]=d[x]+z;
                q.push(make_pair(-d[y],y));
            }
        }
    }
}

SPFA+负环

变量

  • int d[i]\texttt{int d[i]}:点 ii 到源点的最短路长度。
  • int cnt[i]\texttt{int cnt[i]}:点 ii 在队列中出现的次数。
  • bool v[i]\texttt{bool v[i]}:标记节点 ii 是否已经更新完全。

函数

  • bool spfa(int s)\texttt{bool spfa(int s)}:求以 ss 为源点的单源最短路,如果图中有负环,就返回 11,否则返回 00

代码

int d[N],cnt[N];
bool v[N];
bool spfa(int s){
	memset(d,0x3f,sizeof(d));
	memset(v,0,sizeof(v));
	memset(cnt,0,sizeof(cnt));
	queue<int>q;
	d[s]=0;
	v[s]=1;
	q.push(s);
	while(q.size()){
		int x=q.front();
		q.pop();
		v[x]=0;
		cnt[x]++;
		if(cnt[x]>n)
			return 1;
		for(int i=head[x];i;i=nxt[i]){
			int y=ver[i],z=edge[i];
			if(d[y]>d[x]+z){
				d[y]=d[x]+z;
				if(!v[y]){
					q.push(y);
					v[y]=1;
				}
			}
		}
	}
	return 0;
}

Johnson 全源最短路

变量

  • int in[i]\texttt{int in[i]}:点 ii 的入队次数,用于判负环。
  • int h[i]\texttt{int h[i]}:点 ii 的势能。
  • int d[i]\texttt{int d[i]}:点 ii 到源点的最短路。

函数

  • bool spfa(int s)\texttt{bool spfa(int s)}:求 00 点到其它点的最短路,并判负环。
  • void dijkstra(int s)\texttt{void dijkstra(int s)}:求无负边权图的最短路。
  • bool init()\texttt{bool init()}:预处理图并判负环。

代码

struct Johnson{
	int head[N],ver[M<<1],nxt[M<<1],tot=1;
	int vis[N],in[N];
	ll edge[M<<1],h[N],d[N];
	void add(int x,int y,ll z){
		ver[++tot]=y,edge[tot]=z,nxt[tot]=head[x],head[x]=tot;
	}
	bool spfa(int s){
		queue<int>q;
		memset(h,0x3f,sizeof(h));
		memset(vis,0,sizeof(vis));
		memset(in,0,sizeof(in));
		h[s]=0;vis[s]=1;q.push(s);
		while(q.size()){
			int x=q.front();q.pop();
			vis[x]=0;
			for(int i=head[x];i;i=nxt[i]){
				int y=ver[i];
				if(h[y]>h[x]+edge[i]){
					h[y]=h[x]+edge[i];
					if(!vis[y]){
						vis[y]=1;in[y]++;
						q.push(y);
						if(in[y]==n+1)return 0;
					}
				}
			}
		}
		return 1;
	}
	void dijkstra(int s){
		priority_queue<pair<ll,int> >q;
		memset(d,0x3f,sizeof(d));
		for(int i=1;i<=n;i++)d[i]=1e9;
		memset(vis,0,sizeof(vis));
		q.push(make_pair(d[s]=0,s));
		while(q.size()){
			int x=q.top().second;q.pop();
			if(vis[x])continue;
			vis[x]=1;
			for(int i=head[x];i;i=nxt[i]){
				int y=ver[i];
				if(d[y]>d[x]+edge[i]){
					d[y]=d[x]+edge[i];
					q.push(make_pair(-d[y],y));
				}
			}
		}
	}
	bool init(){
		for(int i=1;i<=n;i++)add(0,i,0);
		if(!spfa(0))return 0;
		for(int x=1;x<=n;x++){
			for(int i=head[x];i;i=nxt[i])
				edge[i]+=h[x]-h[ver[i]];
		}
		return 1;
	}
}js;
posted @ 2022-08-28 21:36  luckydrawbox  阅读(8)  评论(0)    收藏  举报  来源