注:我在修炼当中,博客完全是为了自己复习方便看得,如果你不慎点入了我的博客,看看就好,不要相信,误人子弟就不好了- -
先贴模板
Dijkstra
#define inf 0x3fffffff
#define M 105
int dist[M], map[M][M], n;
bool mark[M];
void init ()
{
int i, j;
for (i = 1; i <= n; i++) //i==j的时候也可以初始化为0,只是有时候不合适
for (j = 1; j <= n; j++)
map[i][j] = inf;
}
void dijk (int u)
{
int i, j, mins, v;
for (i = 1; i <= n; i++)
{
dist[i] = map[u][i];
mark[i] = false;
}
mark[u] = true;
dist[u] = 0; //既然上面的map当i==j时不是0,就要这句
while (1)
{
mins = inf;
for (j = 1; j <= n; j++)
if (!mark[j] && dist[j] < mins)
mins = dist[j], v = j;
if (mins == inf)
break;
mark[v] = true;
for (j = 1; j <= n; j++)
if (!mark[j] && dist[v] + map[v][j] < dist[j])
dist[j] = dist[v] + map[v][j];
}
}
Floyd
#define inf 0x3fffffff //注意,太大会溢出
#define M //最大点数
int n, dist[M][M]; //n:实际点数
void init () //有时候需要初始化
{
int i, j;
for (i = 1; i <= n; i++)
for (j = i + 1; j <= n; j++)
dist[i][j] = dist[j][i] = inf;
}
void floyd ()
{
int i, j, k;
for (k = 1; k <= n; k++)
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++) //有的题目会溢出就要自己变通了
if (dist[i][k] + dist[k][j] < dist[i][j])
dist[i][j] = dist[i][k] + dist[k][j];
}
SPFA
#define inf 0x3fffffff
#define M 1005 //最大点数
struct edge
{
int v, w, next;
} e[10005]; //估计好有多少条边
int pre[M], cnt, dist[M], n;
bool inq[M];
//注意初始化
void init ()
{
cnt = 0;
memset (pre, -1, sizeof(pre));
}
//注意双向加边
void addedge (int u, int v, int w) //加边函数,慢慢模拟就会明白的
{
e[cnt].v = v;
e[cnt].w = w;
e[cnt].next = pre[u]; //接替已有边
pre[u] = cnt++; //自己前插成为u派生的第一条边
}
void spfa (int u)
{
int v, w, i;
for (i = 1; i <= n; i++) //对于从1到n的编号
dist[i] = inf, inq[i] = false;
dist[u] = 0;
queue<int> q;
q.push (u);
inq[u] = true;
while (!q.empty())
{
u = q.front();
q.pop();
inq[u] = false;
for (i = pre[u]; i != -1; i = e[i].next)
{
w = e[i].w;
v = e[i].v;
if (dist[u] + w < dist[v])
{
dist[v] = dist[u] + w;
if (!inq[v])
{
q.push (v);
inq[v] = true;
}
}
}
}
}