poj1251 Jungle Roads(Prime || Kruskal)

时间:2023-12-28 15:04:20

题目链接

http://poj.org/problem?id=1251

题意

有n个村庄,村庄之间有道路连接,求一条最短的路径能够连接起所有村庄,输出这条最短路径的长度。

思路

最小生成树问题,使用普利姆算法(Prime)或者克鲁斯卡尔算法(Kruskal)解决。

代码

Prime算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; const int INF = 0xfffffff;
const int N = ;
int n;
int jungle[N][N];
int dist[N]; //记录从起点到其余各点的距离并不断更新 int prime()
{
int min_edge, min_node;
for (int i = ; i < n; i++)
dist[i] = INF;
int now = ;
int ans = ;
for (int i = ; i < n - ; i++)
{
dist[now] = -; //标记结点now+'A'被访问过了
min_edge = INF;
for (int j = ; j < n; j++)
{
if (j != now && dist[j]>=)
{
if (jungle[now][j]>)
dist[j] = min(dist[j], jungle[now][j]);
if (dist[j] < min_edge)
{
min_edge = dist[j]; //选取从当前结点到其余各点的最短路径
min_node = j;
}
}
}
now = min_node;
ans += min_edge; //当前最小生成树的长度
}
return ans;
} int main()
{
//freopen("poj1251.txt", "r", stdin);
while (cin >> n && n)
{
memset(jungle, , sizeof(jungle));
for (int i = ;i < n-;i++)
{
char p, q;
int v, w;
cin >> p >> v;
for (int j = ;j < v;j++)
{
cin >> q >> w;
jungle[p - 'A'][q - 'A'] = w;
jungle[q - 'A'][p - 'A'] = w;
}
}
int ans = prime();
cout << ans << endl;
}
return ;
}

Kruskal算法:

 #include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std; const int N = ;
int s[N], e[N], v[N]; //分别存储每一条路的起点、终点、长度
int p[N]; //并查集使用
int n;
int cnt; //存储有多少条路 bool cmp(int i, int j)
{
return v[i] < v[j];
} int find_root(int x)
{
if (p[x] == -)
return x;
else return find_root(p[x]);
} int kruskal()
{
memset(p, -, sizeof(p));
int r[N];
for (int i = ; i < cnt; i++)
r[i] = i;
sort(r, r + cnt, cmp); //根据路径长度v[]的大小对数组r[]排序
int ans = ;
for (int i = ; i < cnt; i++)
{
int cur = r[i];
int a = find_root(s[cur]);
int b = find_root(e[cur]);
if (a != b)
{
ans += v[cur];
p[a] = b;
}
}
return ans;
} int main()
{
//freopen("poj1251.txt", "r", stdin);
while (cin >> n && n)
{
cnt = ;
char p, q;
int nums, w;
for (int i = ; i < n - ; i++)
{
cin >> p >> nums;
for (int j = ; j < nums; j++)
{
cin >> q >> w;
s[cnt] = p - 'A';
e[cnt] = q - 'A';
v[cnt] = w;
cnt++;
}
}
int ans = kruskal();
cout << ans << endl;
}
return ;
}