【最短路/3大模板】总结【2012-1-22新增前插的spfa】

首先献上模板:【点都是默认为从1到n编号,用dijk和floyd时要注意重边】
①DIJK
#define inf 0x3fffffff#define M 105int 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];}}#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];}#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; } } } }}#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; } } } }}