时间限制: 1 Sec 内存限制: 128 MB
提交: 49 解决: 11
[提交][状态][讨论版]
题目描述
8月12日夜间23:30分左右,天津市滨海新区第五大街与跃进路交口的瑞海公司危险品仓库突发连环爆炸。不仅伤亡了许多人,也造成了巨大损失。在这场灾难中,我们的消防官兵赶到现场救援时,许多发生了不幸。“最帅的逆行”感动了无数的人,在这里,让我们为在现场救援的和失联的消防官兵祈福,为群众祈福。为天津祈福,天佑天津。
现在*地区的消防官兵因为需要日常训练,需要在训练地方架设水管,为了提高训练强度,一般训练的地区高度是不一样的,我们暂时把它们分成几个区域,例如:A区域是练习攀爬的地方,B区域练习跑步,C区域是战士们休闲区域。我们的所有区域可以看成一个N行M列的矩阵。我们不考虑每个区域内需要架设多少水管。我们只考虑将这两个区域连接起来需要的水管长度,这个长度就是这两个区域的高度差。一个区域只能跟它上下左右四块相邻的区域相连通,我们现在想知道最少还需要多长的水管可以连接所有区域。
输入
处理到文件结束,第一行有一个数字T,代表输入的样例组数。然后每组数据第一行是两个正整数N,M(0
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int per[2000020],n,m,map[1020][1020];
struct stu
{
int u,v,w;
}a[2000000];
int cmp(stu x,stu y)
{
return x.w <y.w ;
}
void init()
{
for(int i=1;i<=n*m;i++)
per[i]=i;
}
int find(int x)
{
int r=x;
while(r!=per[r])
r=per[r];
return r;
}
int join(int x,int y)
{
int fx=find(x);
int fy=find(y);
if(fx!=fy)
{
per[fx]=fy;
return true;
}
return false;
}
int main()
{
int t,i,j,d;
scanf("%d",&t);
while(t--)
{
int sum=0,k=0;
scanf("%d%d",&n,&m);
init();
for(i=1;i<=n;i++)
for(j=1;j<=m;j++)
scanf("%d",&map[i][j]);
for(i=1;i<=n;i++)
{
for(j=2;j<=m;j++)
{
d=abs(map[i][j]-map[i][j-1]);
a[k].u=(i-1)*m+j-1;//这里是乘m,不是n,每行有m个数字
a[k].v=(i-1)*m+j;
a[k].w=d;
k++;
}
}
for(j=1;j<=m;j++)
{
for(i=2;i<=n;i++)
{
d=abs(map[i-1][j]-map[i][j]);
a[k].u=(i-2)*m+j;
a[k].v=(i-1)*m+j;
a[k].w=d;
k++;
}
}
sort(a,a+k,cmp);
for(i=0;i<k;i++)
if(join(a[i].u,a[i].v))
sum+=a[i].w;
printf("%d\n",sum);
}
return 0;
}