Dijkstra
int dist[maxnum]; // 表示当前点到源点的最短路径长度
int prev[maxnum]; // 记录当前点的前一个结点
int c[maxnum][maxnum]; // 记录图的两点间路径长度
int n, line; // 图的结点数和路径数
void Dijkstra()
{
bool s[maxnum]; // 判断是否已存入该点到S集合中
for(int i=1; i<=n; ++i) //初始化
{
dist[i] = c[v][i];
s[i] = 0;
if(dist[i] == maxint)
prev[i] = 0;
else
prev[i] = v;
}
dist[v] = 0;
s[v] = 1;
// 依次将未放入S集合的结点中,取dist[]最小值的结点,放入结合S中
// 一旦S包含了所有V中顶点,dist就记录了从源点到所有其他顶点之间的最短路径长度
for(int i=2; i<=n; ++i)
{
int tmp = maxint;
int u = v;
// 找出当前未使用的点j的dist[j]最小值
for(int j=1; j<=n; ++j)
if((!s[j]) && dist[j]<tmp)
{
u = j; // u保存当前邻接点中距离最小的点的号码
tmp = dist[j];
}
s[u] = 1; // 表示u点已存入S集合中
// 更新dist
for(int j=1; j<=n; ++j)
if((!s[j]) && c[u][j]<maxint)
{
int newdist = dist[u] + c[u][j];
if(newdist < dist[j])
{
dist[j] = newdist;
prev[j] = u;
}
}
}
}
SPFA
const int maxn = 1010;
const int inf = 0x7f7f7f7f;
int road[maxn][maxn];
int dis[maxn]; //记录源点到t点的最短路径
int cnt[maxn]; // 记录顶点入队列的次数
int vis[maxn]; //记录顶点是否在队列中,SPFA算法可以入队列多次
void Spfa(int start)
{
for (int i(0); i<num_town; ++i)//初始化
{
dis[i] = MAX;
vis[i] = false;
}
queue<int> Q;
dis[start] = 0;
vis[start] = true;
cnt[start]++;
Q.push(start);
while (!Q.empty()){
int temp = Q.front();
Q.pop();
for (int i=0; i<num_town; ++i)
{
if (dis[temp] + road[temp][i] < dis[i])//存在负权的话,就需要创建一个COUNT数组,当某点的入队次数超过V(顶点数)返回。
{
dis[i] = dis[temp] + road[temp][i];
if (!vis[i])
{
Q.push(i);
vis[i] = true;
cnt[i]++;
//if(cnt[i] >= num_town) 当一个点入队的次数>=n时就证明出现了负环。
//return true;
}
}
}
vis[temp] = false;
}
//return false;
}
/
Floyd
for ( int k = 0; k < 节点个数; ++k )
{
for ( int i = 0; i < 节点个数; ++i )
{
for ( int j = 0; j < 节点个数; ++j )
{
if ( Dis[i][k] + Dis[k][j] < Dis[i][j] )
{
// 找到更短路径
Dis[i][j] = Dis[i][k] + Dis[k][j];
}
}
}
}
最短路算法合集
最新推荐文章于 2021-12-08 22:08:24 发布