prim 与dijkstra的异同 POJ 2485 Highways
来源:互联网 发布:window10 windows.old 编辑:程序博客网 时间:2024/04/19 07:26
题目链接:http://poj.org/problem?id=2485
题意:一个地方F,没有Highways,交通不便,要建 Highways,每个Highway连接两个城镇,所有的Highways都是直线的。
样例输入意思:
T 案例数
N 城镇数
下面N行N列,以矩阵的形式
v1 v2 v3
v1 0 990 692
v2 990 0 179
v3 692 179 0
样例输出意思:
明显路径是 v1-v3-v2,路径中最大的数是692,输出的就是它
思路:
最小生成树问题,一般用prim,kuskal算法 。prim算法是以顶点来扩展的。把每次找到的顶点加入顶点集U,然后下次再找与U相邻且最小的顶点,加入U,依次,得到最小生成树。
参考:http://en.wikipedia.org/wiki/Prim's_algorithm
#include <stdio.h>#include <string.h>#define M 502#define INF 99999int prim[M][M];int visit[M];int Len[M]; //Len[i] 记录顶点集U到i的最短距离,注意区别dijkstra中的dis[i]int n;int ans;int prim_solve(int xx){ int minx; int i,j,k; memset(visit,0,sizeof(visit)); //开始时都未访问 ans = -1; for (i = 1; i <= n; i++) { Len[i] = prim[xx][i]; } Len[xx] = 0; visit[xx] = 1; //此时U中只有起点xx for(i = 1; i< n; i++) // 注意:不能=,因为xx起点已经访问过,所以只需再访问n-1个 { minx = INF; for(j = 1; j <= n; j++ ) //很像dijkstra中的吧,但注意:这里的Len[i]与dijkstra中dis[i]意义相当不同 { //这里找的是:与顶点集U相邻的距离最小值 if ( !visit[j] && Len[j] < minx) { minx = Len[j]; k = j; } } visit[k] = 1; //找到,加入U if (ans < minx) //保存最短路径中最大的一条边,比如样例中692 { ans = minx; } //i=1时,U中只有起点xx和新加入的k,Len[j]与prim[j]比较:就是比较xx到j的距离和新加入U的k顶点到j的距离 //之后,Len[j]就是U到j的最短距离啦,这样把U中所有顶点看成一个,Len[j]就是U到j(V-U中任意一个)的最短距离 //以此类推,i>1 时,每次都把原来的顶点集U到j的距离和新加入的k到j的距离比较,这样得到了新U到j的最短距离 //从而,就得到了新U到V-U中任一顶点的距离,保存在 Len中 for (j = 1; j <= n; j++) { if ( !visit[j] && Len[j] > prim[k][j]) { Len[j] = prim[k][j]; } } } return ans;}int main(){ int T; int i,j; scanf("%d",&T); while(T--) { memset(prim,0,sizeof(prim)); scanf("%d",&n); for(i = 1; i <= n; i++) for(j = 1; j <= n; j ++) { scanf("%d",&prim[i][j]); } printf("%d\n",prim_solve(1)); //以第一个顶点开始,也可以是其他,无所谓,改成2。。。。一样 } return 0;}
你会觉得prim代码实现是来很像dijkstra,参考http://blog.csdn.net/bill_ming/article/details/7578037
prim是计算最小生成树的算法,dijkstra是计算最短路径的算法。
他们都是从几何V-U中不断选出权值最小的顶点加入U,那他们是否可以互用吗?
必然不可以嘛!
他们的不同之处是:
prim是把U中的点看成一个整体,每次寻找V-U中和U距离最小的顶点加入U。而dijkstra是相对于源点V0而言的,每次寻找的是V-U中里V0最近的顶点。
所以:
dijkstra中dis[i]记录的是V0到i的最短距离。
用这样的for循环来更新dis,结果dis[j]是比较源点V0直接到j 和 源点V0经过k到j的最短距离所得结果
for(j = 1; j <= n; j++)
{
if ( !visit[j] && dis[j] > dis[k] + map[k][j])
{
dis[j] = dis[k] + map[k][j];
}
}
而prim中Len[i]记录的是顶点集U(看成整体)到i的最短距离
用这样的for循环来更新顶点集U到V-U中任一顶点的距离,比较的是加入k之前顶点集到j的距离 和 k 到j的距离 。
得到的就是包含k的新顶点集U到j的最短距离。 (感谢罗康琦大牛!!!)
//i=1时,U中只有起点xx和新加入的k,Len[j]与prim[j]比较:就是比较xx到j的距离和新加入U的k顶点到j的距离
//之后,Len[j]就是U到j的最短距离啦,这样把U中所有顶点看成一个,Len[j]就是U到j(V-U中任意一个)的最短距离
//以此类推,i>1 时,每次都把原来的顶点集U到j的距离和新加入的k到j的距离比较,这样得到了新U到j的最短距离
//从而,就得到了新U到V-U中任一顶点的距离,保存在 Len中
for (j = 1; j <= n; j++)
{
if ( !visit[j] && Len[j] > prim[k][j])
{
Len[j] = prim[k][j];
}
}
他们的区别就知道了。所以不能互用啊,prim还是乖乖算最小生成树吧,dijkstra还是继续管计算最短路径吧
举个例子就知道他们不能乱来了:
有四个顶点(v0, v1, v2, v3)和四条边且边值定义为(v0, v1)=20, (v0, v2)=10, (v1, v3)=2, (v3, v2)=15的图,用Prim算法得到的最小生成树中v0跟v1是不直接相连的,也就是在最小生成树中v0v1的距离是v0->v2->v3->v1的距离是27,而用Dijkstra算法得到的v0v1的距离是20,也就是二者直接连线的长度。
SO。。。。
- prim 与dijkstra的异同 POJ 2485 Highways
- prim 与dijkstra的异同 POJ 2485 Highways
- Prim算法与Dijkstra的异同
- Dijkstra算法与Prim算法的异同
- Highways POJ 2485【Prim】
- poj 2485 Highways ( prim )
- poj 2485 Highways(prim)
- POJ 2485 Highways (kruskal+prim)
- POJ 2485 Highways (MST.Prim)
- Prim算法和Dijkstra算法的异同
- POJ 2485 Highways(prim算法)
- poj 2485 highways(prim)
- poj 2485 Highways prim最小生成树
- POJ 2485 Highways (prim最小生成树)
- POJ 2485 Highways(Prim 和 Kruskal)
- POJ 2485 Highways 【最小生成树Prim】
- Poj 1751 Highways(prim)
- prim 与 dijkstra 的比较
- SAP control编程快速入门
- V4L2 - Linux下视频驱动模型
- 虚幻4引擎游戏Demo截图曝光 效果绝对震撼
- Android avd 在电脑上创建sdcard
- 模式识别经典算法——LDA
- prim 与dijkstra的异同 POJ 2485 Highways
- 男人帮经典语录:
- 教你如何查看端口的使用情况(哪些程序使用了哪些端口)
- Drupal介绍(Drupal笔记一)
- 野人过河问题
- Hardcoded string "下一步", should use @string resource警告
- Struts2默认的配置
- ASP.NET 用 Global.asax 的Application_BeginRequest 事件过滤恶意提交
- 我的图片服务器和WEB应用服务器相分离的简单方案