http://acm.hdu.edu.cn/showproblem.php?pid=5253
2 4 3 9 12 4 7 8 56 32 32 43 21 12 12 2 3 34 56 56 12 23 4
Case #1: 82 Case #2: 74
#include <cstdio> #include <cstring> #include <cmath> #include <algorithm> #define INF 0x3f3f3f3f #define N 1010 using namespace std; struct node { int u,v; int len; // friend bool operator < (node a,node b) // { // return a.len<b.len; // } }; int cmp(node a,node b) { return a.len<b.len; } node edge[N*N*2];//这里开大点,因为一个节点有至少有两个节点与他连接,否则会一直错 int map[N][N]; int per[N*N]; int n,m; int i,j,k; int num; void init() { for(i=0;i<=n*m;++i) per[i]=i; } int find(int x) { if(per[x]==x) return x; return per[x]=find(per[x]); // while(x!=per[x]) // x=per[x]; // return x; } bool join(int x,int y) { int fx=find(x); int fy=find(y); if(fx!=fy) { per[fx]=fy; return 1; } return 0; } void Kruscal() { int sum=0; for(i=0;i<k;++i) { if(join(edge[i].u,edge[i].v)) { sum+=edge[i].len; } } printf("%d\n",sum); } int main() { int T; scanf("%d",&T); num=0; while(T--) { scanf("%d%d",&n,&m); init(); k=0; int ss; for(i=1;i<=n;++i) { for(j=1;j<=m;++j) { node t; // per[ss]=ss; scanf("%d",map[i]+j); if(i>1) { ss=(i-1)*m+j; t.u=ss; t.v=ss-m; t.len=abs(map[i][j]-map[i-1][j]); edge[k++]=t; } if(j>1) { ss=(i-1)*m+j; t.u=ss; t.v=ss-1; t.len=abs(map[i][j]-map[i][j-1]); edge[k++]=t; } } } sort(edge,edge+k,cmp); printf("Case #%d:\n",++num); Kruscal(); } return 0; }