Dijkstra&Floyd笔记

单源最短路径

给定一个带权dedeG=(V,E)G=(V,E),求某点到某点的最短距离。

DijkstraDijkstra算法

将图G中所有的顶点v分成两个顶点集合a & b。以v为源点已经确定了最短路径的终点并入a集合中,a初始时只含顶点v,b则是尚未确定到源点v最短路径的顶点集合。然后每次从b集合中选择a集合点中到b路径最短的那个点,并加入到集合a中,并把这个点从集合b删除,直到b集合为空为止。

代码如下:

Var s,e,n,m,a,b,c,i,j:longint;
f:array[0..1005] of boolean;
d:array[0..1005] of longint;
w:array[0..1005,0..1005] of longint;

procedure dj(x:longint);
Var i,j,k,pos,min:longint;
Begin
        f[x]:=true;
        d:=w[x];
        for i:=1 to n-1 do
        Begin
                min:=maxlongint;
                for j:=1 to n do
                Begin
                        if (not f[j]) and (d[j]<min) then
                        Begin
                                min:=d[j];
                                pos:=j;
                        end;
                end;
                f[pos]:=true;

                for j:=1 to n do
                Begin
                        if (not f[j]) and (d[pos]+w[pos,j]<d[j]) then
                        Begin
                                d[j]:=w[pos,j]+d[pos];
                        end;
                end;
        end;
end;

Begin
        read(n,m);

        for i:=1 to n do
        Begin
                for j:=1 to n do
                Begin
                        w[i,j]:=100000;
                end;
        end;

        for i:=1 to m do
        Begin
                read(a,b,c);
                w[a,b]:=c;
                w[b,a]:=c;
        end;
        read(s,e);
        dj(s);

        write(d[e]);
end.

FloydWarshallFloyd-Warshall算法

此算法使用邻接矩阵来储存边,通过考虑最佳子路径来得到最佳路径。 从任意一条单边路径开始。所有两点之间的距离是边的权,或者无穷大,如果两点之间没有边相连。对于每一对顶点 u 和 v,看看是否存在一个顶点 w 使得从 u 到 w 再到 v 比己知的路径更短,如果是,那么更新它。

代码如下:

Var i,j,k,a,b,n,m,s,e:longint;
    w:array[0..1000,0..1000] of longint;
Begin
        read(n,m);
        for i:=1 to n do
        Begin
                for j:=1 to n do
                Begin
                        if i<>j then w[i,j]:=maxint
                        else w[i,j]:=0;
                end;
        end;
        for i:=1 to m do
        Begin
                read(a,b,w[a,b]);
                w[b,a]:=w[a,b];
        end;
        read(s,e);

        for k:=1 to n do
        Begin
                for i:=1 to n do
                Begin
                        for j:=1 to n do
                        Begin
                                if w[i,k]+w[k,j]<w[i,j] then
                                Begin
                                        w[i,j]:=w[i,k]+w[k,j];
                                end;
                        end;
                end;
        end;

        write(w[s,e]);
end.

SPFASPFA

const int maxn=100005;

int dis[maxn], head[maxn], cnt=0;
bool vis[maxn];
struct Edge {
	int to, next, data;
} edge[maxn<<1];
void add(int u , int v , int val) {
	edge[++cnt]=(Edge){v , head[u] , val};
	head[u]=cnt;
}

void spfa(int st) {
	memset(dis , 127 , sizeof(dis));
	queue<int> que;
	memset(vis , false , sizeof(vis));
	que.push(st); dis[st]=0; vis[st]=true;
	while (!que.empty()) {
		int u=que.front(); que.pop();
		vis[u]=false;
		for (re int i=head[u]; i; i=edge[i].next) {
			if (dis[u]+edge[i].data<dis[edge[i].to]) {
				dis[edge[i].to]=dis[u]+edge[i].data;
				if (!vis[edge[i].to]) {
					que.push(edge[i].to);
					vis[edge[i].to]=true;
				}
			}
		}
	}
}
posted @ 2019-02-11 22:47  willbe233  阅读(52)  评论(0)    收藏  举报