最短路基础模板(自用)

  • dijkstra算法:

  • //求从x到y的最短路
    
    void dijkstra(int x,int y) {
        memset(visit, 0, sizeof(visit));
        for (int i = 1; i <= n; ++i) {
            dist[i] = map[x][i];
        }
        for (int i = 1; i <= n; ++i) {
            int a=1, minn = INF;
            for (int j = 1; j <= n; ++j) {
                if (!visit[j] && dist[j] < minn) {
                    a = j;
                    minn = dist[j];
                }
            }
            visit[a] = 1;
            for (int j = 1; j <= n; ++j) {
                if(!visit[j]&&dist[j]>dist[a]+map[a][j])
                    dist[j] =dist[a] + map[a][j];
            }
        }
        printf("%d\n",dist[y]);
    }
    

    Bellman-Ford算法、SPFA:

const int MAXN=1e5+7;

struct edge {
	int v, u;
	int cost;
}e[MAXN];


//Bellman_Ford算法

bool Bellman_Ford(int s) {
    //第一部分初始化
	for (int i = 1; i <= n; ++i) { 
		dist[i] = INF;
	}
	dist[s] = 0;
    //第二部分进行松弛操作
	for (int j = 1; j < n; ++j) {  //检查n-1个结点
		for (int i = 1; i <= m; ++i) { //m为边数
			int x = e[i].u, y = e[i].v;
			if (dist[y]>dist[x]+e[i].cost)
				dist[y] = dist[x] + e[i].cost);
		}
	}
    //第三部分判断是否存在负环
        for (int i = 1; i <= n;++i) {
		int x = e[i].u, y = e[i].v;
		if (dist[y] > dist[x] + e[i].cost) {
			return false;
		}
	}
	return true;
}

//SPFA

int cnt[1010]; //用于记录入队次数
int visit[1010]; // 用于记录点是否入队

bool SPFA(int s) {
	queue<int> q;
	memset(visit, 0, sizeof(visit));
	memset(cnt, 0, sizeof(cnt));
	for (int i = 1; i <= n; ++i) {
		dist[i] = INF;
	}
	dist[s] = 0;
	visit[s] = 1;
	q.push(s);
	cnt[s]++;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		visit[u] = 0;
		for (int i = 1; i <= n; ++i) {
			if (map[u][i] != INF) {
				if (dist[i] > dist[u] + map[u][i]) {
					dist[i] = dist[u] + map[u][i];
					if (!visit[i]) {
						q.push(i);
						cnt[i]++;
						if (cnt[i] >= n) //当该点入队次数大于等于n时,说明图中存在带负权的环,无法求出最短路,则返回false(负环判断)
							return false;
						visit[i] = 1;
					}
				}
			}
		}
	}
	return true;
}
  • Floyd算法:

//一般情况
void Floyd() {
    for(int k=1;k<=n;++k){
	    for (int i = 1; i <= n; ++i) {
		    for (int j = 1; j <= n; ++j) {
		    	if (dist[i][k] < INF&&dist[k][j] < INF) {
		    		dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
	    		}
	       	}
	    }
    }
}


//用于每次都有新的点加入时求最短路
void Floyd(int k) {
	for (int i = 0; i < n; ++i) {
		for (int j = 0; j < n; ++j) {
			if (dist[i][k] < INF&&dist[k][j] < INF) {
				dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
			}
		}
	}
}

猜你喜欢

转载自blog.csdn.net/weixin_43821265/article/details/86625880