#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXM = 10050;
const int MAXN = 110;
struct Edge
{
int u, v, w;
};
Edge edges[MAXM];
int parent[MAXN];
int n, m;
void UFset()
{
int i;
for(i = 0; i < n; ++i)
{
parent[i] = -1;
}
}
int Find_Parent(int x)
{
int s;
for (s = x; parent[s] >= 0; s = parent[s])
;
while(s != x)
{
int tmp = parent[x];
parent[x] = s;
x = tmp;
}
return s;
}
void Union(int u, int v)
{
int r1 = Find_Parent( u );
int r2 = Find_Parent( v );
int tmp = parent[r1] + parent[r2];
if (parent[r1] > parent[r2])
{
parent[r1] = r2;
parent[r2] = tmp;
}
else
{
parent[r2] = r1;
parent[r1] = tmp;
}
}
int Kruskal()
{
int i;
int sum = 0;
int u, v;
UFset();
int num = 0;
for (i = 0; i < m; ++i)
{
u = edges[i].u;
v = edges[i].v;
if (Find_Parent(u) != Find_Parent(v))
{
sum += edges[i].w;
num++;
Union(u, v);
}
if(num >= n-1)
break;
}
return sum;
}
int cmp(const void* a, const void* b)
{
Edge* aa = (Edge *)a;
Edge* bb = (Edge *)b;
if(aa->w > bb->w)
return 1;
else
return -1;
}
int main()
{
int sum;
int M[MAXN][MAXN];
int flag[MAXN][MAXN];
int i, j;
int Q, a, b;
while(~scanf("%d", &n))
{
int mi = 0;
memset(flag, 0, sizeof(flag));
for (i = 0; i < n; ++i)
{
for (j = 0; j < n; ++j)
{
cin>>M[i][j];
}
}
cin>>Q;
for(i = 0; i < Q; ++i)
{
cin>>a>>b;
flag[a-1][b-1] = 1;
}
for (i = 0; i < n; ++i)
{
for (j = i+1; j < n; ++j)
{
if(flag[i][j])
{
edges[mi].u = i;
edges[mi].v = j;
edges[mi++].w = 0;
}
else
{
edges[mi].u = i;
edges[mi].v = j;
edges[mi++].w = M[i][j];
}
}
}
m = mi;
qsort(edges, m, sizeof(edges[0]), cmp);
sum = Kruskal();
cout<<sum<<endl;
}
return 0;
}
poj 2421 Constructing Roads (Kruskal)
最新推荐文章于 2020-11-27 22:09:48 发布