U2FsdGVkX1991LkurAWwEVvexSbk82zUO+stQ6myqhiGAYfXi4t8g0fy0Lc7kV2H38+oiVPFJ5EFE6yTkARTL8BWVQwxf17p4JFNPJTSvYMCLr03MCF3J23owqVWuDtYrNzhC+sIldFcMj+LjpiJLdGTW9P3GF3HVSdwGI3QOntxrtEHm1LgG0Sp97docEaIu8MKlFKEVOQRr/K+u3PeQb9HnWuYQRz4D1h5a8QxDyWg2ozJJrQQrSrJJwn7VpXX0Mf2mTIH6WIbHOkmrEg33kLHJq4nFb5zOEpWZOip0XJxA7An/nI5qw6e1d2gmDQBJAKauCsnj9pRUUQaT2RWV/EtJjSow5VKCYoNSOn8OSYBtF6/LQg7XJhgyH9B9Y1m+0MmAqhNT7gj0eAswhoiaQNbHaxZa7p9+OLI/2s29uWA2fxVEZSu3GvfLWMmJqicv2XH4G1vMsbzLIWLTmgoNWmMBiWGzMEx0Otx2TsTZtjfCP3Om0izrqLjE50Cbs4KtZZzw4RLFHR/REYrM0RyQ5H3j2wkKyM+Ji8QHwl3QbLfQCVNeMcdVa6XWDNI30pLm9EXofV25E9KV3bAwAnIwsATiL/v+q1eBwq+f8DjRTNuaq+7CHLWqEukIRt2stFeYu2jXTRJ9kc8uJ8P0c1RP1tGby66IW+v1RWrrO9WrTlwHAToSY1UiC74KzpZnKMuLtWJpg3rglaiHgZwdO03CIDh9cfR6Hrn3DdsbPofDUjvM/7Q8XSVTG9zqneoCMCLkVvt/HiD5exzX/dd/DSNh9i3yHj7WMPfhmbl0U79TdkITNUCIBB+bt9DNmMsfHLkH2jjbKmAEAPvdcVTgjPMxw==
aes
SPFA
void Spfa()
{
for (int i(0); i<num_town; ++i)//初始化
{
dis[i] = MAX;
visited[i] = false;
}
queue<int> Q;
dis[start] = 0;
visited[start] = true;
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 (!visited[i])
{
Q.push(i);
visited[i] = true;
}
}
}
visited[temp] = false;
}
}
Dijk
#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];
}
vector后插的SPFA
#define inf 0x3fffffff
#define M 105 //最大点数
struct son{
int v, w;
};
vector<son> g[M];
bool inq[M]; //入队列标记
int dist[M], n; //n:实际点数
void init ()
{
for (int i = 1; i <= n; i++)
g[i].clear();
}
void spfa (int u)
{
int i, v, w;
for (i = 1; i <= n; i++)
{
dist[i] = inf;
inq[i] = false;
}
queue<int> q;
q.push (u);
inq[u] = true;
dist[u] = 0;
while (!q.empty())
{
u = q.front();
q.pop();
inq[u] = false;
for (i = 0; i < g[u].size(); i++)
{
v = g[u][i].v;
w = g[u][i].w;
if (dist[u] + w < dist[v])
{
dist[v] = dist[u] + w;
if (!inq[v])
{
q.push (v);
inq[v] = true;
}
}
}
}
}
模拟前插的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;
}
}
}
}
}