您的位置:首页 > 其它

最小生成树 Prim 算法HDU 2122 Ice_cream’s world III

2015-04-02 17:45 591 查看
Prim算法 :

根据图中的顶点进行操作,而克鲁斯卡尔算法是先将边进行排序,从小到大加入集合。

在图中任选一点作为开始节点,把这个顶点加入已经访问节点的集合。
求出这样一点的相邻节点的距离。并找出最短的一条边。这是第一步,找到的第一条边。把这一个节点加入已经访问过的集合。
在已经访问过的集合中,再次寻找最短的一条边。这一次还要考虑之前加入的顶点。因为之前的一个顶点到所有的距离已经求出。这一次就可以判断此点到其他点的距离,若距离小于之前对应的距离,则更新。

#include <iostream>
#include <cstdio>
#include <cstring>
#define INF 0x7fffffff
using namespace std;
int n, m;
int mymap[10010][10010];

void prim()
{
int visited[10010], low[10010], ans = 0;
memset(visited, 0, sizeof(visited));
int pos = 0;
for (int i = 1; i < n; i++)
{
low[i] = mymap[pos][i];
}
visited[pos] = 1;
for (int i = 1; i < n; i++)<span style="white-space:pre">	</span>//这里一定是N - 1 次
{
int mincost = INF;
for (int j = 0; j < n; j++)
{
if (!visited[j] && mincost > low[j])
{
mincost = low[j];
pos = j;
}
}
if (mincost == INF)
{
printf("impossible\n\n");
return ;
}
visited[pos] = 1;
ans += mincost;
for (int i = 0; i < n; i++)
{
if (!visited[i] && mymap[pos][i] < low[i])
{
low[i] = mymap[pos][i];
}
}
}
printf("%d\n\n", ans);
}

int main()
{
while (scanf("%d%d", &n, &m) != EOF)
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
if (i == j)
{
mymap[i][j] = 0;
}
else
{
mymap[i][j] = INF;
}
}
}
while (m--)
{
int a, b, c;
scanf("%d%d%d", &a, &b, &c);
if(mymap[a][b] > c)
{
mymap[a][b] = mymap[b][a] = c;
}

}
prim();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  prim