-
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;
}
//一般情况
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]);
}
}
}
}