用最小生成树kruskal算法求最小建造长度
#include<string.h>
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
using namespace std;
struct edge{
int b, e, len;
};
struct cmpe{
bool operator()(edge e1, edge e2)
{
return e1.len > e2.len;
}
};
priority_queue<edge, vector<edge>, cmpe> q;
int par[200];
int find(int x)
{
int tx = x;
while (par[tx] >= 0)
tx = par[tx];
while (x != tx)
{
int nx = par[x];
par[x] = tx;
x = nx;
}
return tx;
}
void uni(int x, int y)
{
if (par[x] == par[y])
{
par[x]--;
par[y] = x;
}
else if (par[x] < par[y])
par[y] = x;
else
par[x] = y;
}
int kruskal(int n)
{
int res = 0;
for (int i = 0; i < n-1;)
{
edge te = q.top();
q.pop();
int pb = find(te.b);
int pe = find(te.e);
if (pb != pe)
{
uni(pb, pe);
i++;
res += te.len;
}
}
return res;
}
int main()
{
int n;
while (cin >> n)
{
while (!q.empty())
q.pop();
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
{
int clen;
cin >> clen;
q.push(edge{i,j,clen});
}
int Q;
cin >> Q;
memset(par, -1, sizeof(par));
for (int i = 0; i < Q; i++)
{
int b, e;
cin >> b >> e;
int pb = find(b-1);
int pe = find(e-1);
if (pb != pe)
{
uni(pb, pe);
n--;
}
}
cout << kruskal(n) << endl;
}
return 0;
}