最小生成树模板题
AC代码:
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
const int maxn = 2*1e6;
int Map[1000][1000];
int father[100005];
int N,M,cnt;
int dir[2][2] = {{1,0},{0,1}}; //向下,向右
struct Edge
{
int u;
int v;
int w;
}edge[maxn];
void buildGraph()
{
int u,v,x,y;
for(int i = 0; i < N; i++)
{
for(int j = 0; j < M; j++)
{
u = i*M+j;
for(int k = 0; k < 2; k++)
{
x = i + dir[k][0];
y = j + dir[k][1];
if(x>=0&&x<N&&y>=0&&y<M)
{
v = x*M+y;
edge[cnt].u = u;
edge[cnt].v = v;
edge[cnt].w = abs(Map[i][j]-Map[x][y]);
cnt++;
}
}
}
}
}
bool cmp(Edge a,Edge b)
{
return a.w < b.w;
}
void initSet()
{
for(int i = 0; i < M*N; i++)
father[i] = i;
}
int findSet(int x)
{
int temp = x;
while(x != father[x])
{
x = father[x];
}
while(temp != father[temp])
{
temp = father[temp];
father[temp] = x;
}
return x;
}
void unionSet(int u,int v)
{
father[u] = v;
}
void kruskal()
{
initSet();
int mst = 0;
int i = 0;
int num = 0;
while(i < cnt)
{
int u = edge[i].u;
int v = edge[i].v;
int fu = findSet(u);
int fv = findSet(v);
if(fu != fv)
{
unionSet(fu,fv);
mst += edge[i].w;
num++;
if(num == M*N-1)
break;
}
i++;
}
printf("%d\n",mst);
}
int main()
{
int T,Case = 0;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&N,&M);
for(int i = 0; i < N; i++)
for(int j = 0; j < M; j++)
scanf("%d",&Map[i][j]);
cnt = 0;
buildGraph();
sort(edge,edge+cnt,cmp);
printf("Case #%d:\n",++Case);
kruskal();
}
return 0;
}