`

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

阅读更多



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


第一题:http://acm.hdu.edu.cn/showproblem.php?pid=2544
灰常水,floyd、dijk、spfa都可以

第二题:http://acm.hdu.edu.cn/showproblem.php?pid=2066
简单题,多源多终点,spfa、dijk都很快解决

第三题:http://acm.hdu.edu.cn/showproblem.php?pid=2112
用STL的map把地名映射到编号就可以套模板了,注意路是双向的就行了

第四题:http://acm.hdu.edu.cn/showproblem.php?pid=1874
和第一题一样的水

第五题:http://acm.hdu.edu.cn/showproblem.php?pid=1142
最短路+记忆化搜索
详情:http://972169909-qq-com.iteye.com/blog/1149589


第六题:http://acm.hdu.edu.cn/showproblem.php?pid=1385
floyd记忆路径
详情:http://972169909-qq-com.iteye.com/blog/1150803

第七题:http://acm.hdu.edu.cn/showproblem.php?pid=1548
水题,构图后直接dijk或spfa就可以了

第八题:http://acm.hdu.edu.cn/showproblem.php?pid=1217
floyd的灵活运用
详情:http://972169909-qq-com.iteye.com/blog/1149095

第九题:http://acm.hdu.edu.cn/showproblem.php?pid=2680
简单题,多起点单终点,反过来dijk或者spfa就可以了,注意路是单向的,所有路都要反过来,逆向思维

第十题:http://acm.hdu.edu.cn/showproblem.php?pid=2923
题目意思可能比较难懂,而且有重边,floyd
详情:http://972169909-qq-com.iteye.com/blog/1150818

第十一题:http://acm.hdu.edu.cn/showproblem.php?pid=2962
直接枚举或二分枚举+最短路
详情:http://972169909-qq-com.iteye.com/blog/1159652

第十二题:http://acm.hdu.edu.cn/showproblem.php?pid=2722
这题主要是构图麻烦,会用sscanf就比较好做了,构好图之后就是水题了

第十三题:http://acm.hdu.edu.cn/showproblem.php?pid=1690
暴力构图,枚举2点间距离,根据表格定好花费,然后直接floyd就可以了【注意数太大要用64位,无穷大定为-1比较好处理】

第十四题表示压力好大……

第十五题:http://acm.hdu.edu.cn/showproblem.php?pid=1596
floyd水题

第十六题:http://acm.hdu.edu.cn/showproblem.php?pid=1598
并查集+贪心 或 二分枚举+最短路
详情:http://972169909-qq-com.iteye.com/blog/1159593

第十七题表示不想做……

第十八题:http://acm.hdu.edu.cn/showproblem.php?pid=2363
枚举高度差+最短路,比较容易错
详情:http://972169909-qq-com.iteye.com/blog/1159650

第十九题表示很蛋疼……

第二十题:http://acm.hdu.edu.cn/showproblem.php?pid=2833
一题比较难的记忆化搜索+最短路【或dp+最短路】
详情:http://972169909-qq-com.iteye.com/blog/1159661




3
2
分享到:
评论

相关推荐

    ACM/ICPC模板

    --SPFA(最短路快速算法) // thanks to love8909 几何相关 --初等几何学 --多边形几何 --几种凸包算法 --半平面交算法 --旋转卡壳算法 数据结构 --可合并堆(左偏树实现) --树状数组 --Trie树 //thanks to love8909 ...

    最短路的Floyd-Dijkstra-Spfa板子

    做ACM最短路问题普遍算法的Floyd-Dijkstra-Spfa板子..

    最短路SPFA

    SPFA入门,很好的入门指南。值得一下!

    图论- 最短路- Bellman-Ford 算法与 SPFA.rar

    图论- 最短路- Bellman-Ford 算法与 SPFA.rar

    有向图的spfa模板

    spfa模板,双向图的,但是里面也有介绍改成单向图的。 实际是freepascal的,但是没有分类,只好放到C/C++分类里了,希望能帮到大家

    ACM图论模板合集.pdf

    图论--最短路--第K短路(IDA*)(IDA Star)模板 传递闭包: 传递闭包 欧拉与哈密尔顿路径: 欧拉回路 图论--欧拉回路--弗罗莱算法模板 LCA: 图论--LCA--Tarjan(离线) 图论--LCA--树上...

    cpp代码-SPFA模板

    cpp代码-SPFA模板

    SPFA算法模板

    求单源最短路的SPFA算法的全称是:Shortest Path Faster Algorithm。 SPFA算法是西南交通大学段凡丁于1994年发表的. 从名字我们就可以看出,这种算法在效率上一定有过人之处。 很多时候,给定的图存在负权边,这时...

    SPFA.cpp SPFA算法

    最短路SPFA算法。SPFA(Shortest Path Faster Algorithm)算法是求单源最短路径的一种算法,它是Bellman-ford的队列优化,它是一种十分高效的最短路算法。存在负权边时使用。

    STL实现的容易理解的二位spfa模板

    STL实现的,看完了一定会懂了的。我就是看的这个呢亲

    最短路课件(链式前向星+堆优化+SPFA)

    最短路课件(链式前向星+堆优化+SPFA)

    队列优化的Bellmanford最短路算法(SPFA)C++实现

    使用C++实现的Queue improved Bellman-Ford单源最短路算法,在国内还被叫做SPFA。这个程序输入一个图,找到图中的一个点,这个点到最远点的长度最短。图使用邻接表保存。

    图论,ACM SPFA 和Bellman_ford.ppt 最短路算法

    这里面的内容是个PPT,介绍的很好,如果你想更加的清楚 SPFA 和Bellman_ford.ppt 最短路算法的原理,这是个不错的选择

    最短路全家桶(Floyd,Dijkstra,SPFA)

    最短路全家桶(Floyd,Dijkstra,SPFA)量大管饱

    最短路模板(详细注解)

    可以做刷题的模板哦!!!可以好好理解哦

    常用算法代码

    | BELLMANFORD 单源最短路 O(VE) 4 | SPFA(SHORTEST PATH FASTER ALGORITHM) 4 | 第 K 短路(DIJKSTRA) 5 | 第 K 短路(A*) 5 | PRIM 求 MST 6 | 次小生成树 O(V^2) 6 | 最小生成森林问题(K 颗树)O(MLOGM). ...

    SPFA算法.ppt

    基本思想 用一个队列来进行维护。初始时将源加入队列。每次从队列中取出一个元素,并对所有与他相邻的点进行松弛,若某个相邻的点松弛成功,则将其入队。...d[i]:起点s到i的临时最短路长度 松驰的结果是使j的d值减小

    spfa.cpp 算法spfa的板子

    自己打的spfa算法板子。包含邻接表的两种形式,邻接矩阵Map;此代码不完全,(使用是要注释掉部分的)在使用时要结合题意更改。望采纳!

Global site tag (gtag.js) - Google Analytics