HDU - 1102 Prim &( kruskal 并查集 优先队列)
Prim
只需要解决已经联通的道路这一个问题(这里可以将已联通的城市之间的距离设置为0)
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n, m, map[105][105], Min[105];
bool B[105];
while (cin >> n)
{
int MST = 0;
memset(B, true, sizeof(B));
memset(Min, 0x3f3f3f3f, sizeof(Min));
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
scanf("%d", &map[i][j]);
cin >> m;
int t1, t2;
for (int i = 0; i < m; i++)
{
scanf("%d%d", &t1, &t2);
map[t1][t2] = map[t2][t1] = 0;//解决已联通的问题
}
int k;
/*******prim主体********/
Min[1] = 0;
for (int i = 1; i <= n; i++)
{
k = 0;
for (int j = 1; j <= n; j++)
{
if (B[j] && Min[j] < Min[k])
k = j;
}
MST += Min[k];
B[k] = false;
for (int j = 1; j <= n; j++)
{
if (B[j] && Min[j] > map[j][k])
Min[j] = map[j][k];
}
}
/*******************/
cout << MST << endl;
}
return 0;
kruskal使用优先队列存储可以将n^2的复杂度缩小到nlogn!!此外还可以用vector和邻接矩阵
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std;
struct Node
{
int u, v, w;//u,v是边的两个顶点,w为边长(权值)
};
int pre[110];//用于并查集
struct tmp//重写
{
bool operator() (Node a, Node b)
{
return a.w > b.w;
}
};
int find(int x)//路径压缩优化的find
{
if (x != pre[x])
pre[x] = find(pre[x]);
return pre[x];
}
void merge(int a, int b)//合并结点
{
int t1 = find(a);
int t2 = find(b);
if (t1 != t2)
pre[t1] = t2;
}
int main()
{
int n, m;
while (cin >> n)
{
priority_queue <Node, vector<Node>, tmp > q;//定义一个优先队列
int ans = 0;
for (int i = 0; i <= n; i++)
pre[i] = i;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
{
Node t;
t.u = i; t.v = j;
cin >> t.w;
q.push(t);
}
cin >> m;
int t1, t2;
for (int i = 0; i < m; i++)
{
cin >> t1 >> t2;
if (find(t1) != find(t2))
merge(t1, t2);
}
while (!q.empty())
{
int t1 = find(q.top().u);
int t2 = find(q.top().v);
if (t1!=t2)
{
ans += q.top().w;
merge(t1,t2);
}
q.pop();
}
cout << ans << endl;
}
return 0;
}