解法:kruskal+并查集
根据数据规模不能用搜索
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s) memset(a,x,(s)*sizeof a[0])
#define mem(a,x) memset(a,x,sizeof a)
#define ysk(x) (1<<(x))
typedef long long ll;
//const int INF = 0x3f3f3f3f ;
const int maxn= 1000 ;
int kase,T,n,m,nedge,N;
int h[maxn+3][maxn+3];
int dir[2][2]= { {+1,0},{0,+1} };
int par[(maxn+3)*(maxn+3)];
bool in(int x,int y) { return 1<=x&&x<=n&&1<=y&&y<=m;}
int get_id(int x,int y) { return (x-1)*m+y; }
struct Edge
{
int x,y,w;
Edge(){}
Edge(int x,int y,int w):x(x),y(y),w(w){}
bool operator<(const Edge e)const
{
return w<e.w;
}
}e[ 2*(maxn+3)*(maxn+3) ];
void init()
{
nedge=0;
for1(i,N) par[i]=i;
}
int find(int x) { return x==par[x]?x:par[x]=find(par[x]); }
void MST()
{
sort(e,e+nedge);
// printf("nedge=%d\n",nedge);
int ans=0,cnt=0;
for(int i=0;i<nedge&&cnt<N-1;i++)
{
int x=e[i].x,y=e[i].y,w=e[i].w;
int tx=find(x),ty=find(y);
if(tx==ty) continue;
par[tx]=ty;
ans+=w;
cnt++;
// printf("connect -----%d -------%d\n",x,y);
}
printf("Case #%d:\n%d\n",++kase,ans);
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);N=n*m; init();
for1(i,n) for1(j,m) scanf("%d",&h[i][j]);
for1(i,n) for1(j,m)
{
int id=get_id(i,j);
for0(k,2)
{
int ti=i+dir[k][0],tj=j+dir[k][1];
if(!in(ti,tj)) continue;
int id2=get_id(ti,tj);
e[nedge++]=Edge(id,id2,abs(h[i][j]-h[ti][tj]) );
}
}
MST();
}
return 0;
}
长期没写代码,find函数还写错了,结果超时,return x==par[x]?x:par[x]=find(par[x])
写成了return x==par[x]?x:find(par[x])