码迷,mamicode.com
首页 > 其他好文 > 详细

hdu 5253 连接的管道(百度之星初赛)

时间:2015-09-29 01:05:17      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

题意:n*m的矩阵,每个格子有一个值代表高度,现在需要灌溉所有的格子,管子的长度为高度差,求最小的管长之和;

思路:最小生成树kru算法,保存每个点到其左边和上边的点的高度差,比赛时想不到;

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int mm[1010][1010];
int fa[9000100];
int t,n,m,cnt;
struct node{
  int u,v;
  int len;
  bool operator <(const node& a)const{
    return len<a.len;
  }
};
node edge[5001000];
void init(){
  for(int i=0;i<=n*m;i++){
    fa[i]=i;
  }
}
int f(int x){
    return x==fa[x]?x:fa[x]=f(fa[x]);
}
int combine(int a,int b){
   int t1=f(a);
   int t2=f(b);
   if(t1!=t2){
     fa[t1]=t2;
     return 1;
   }
   return 0;
}
int solve(){
   int sum=0;
   init();
   for(int i=0;i<cnt;i++){
     if(combine(edge[i].u,edge[i].v)){
            sum+=edge[i].len;
     }
   }
   return sum;
}
int main(){
    int i,j,k,ans,pos,cas;
    scanf("%d",&t);
    for(cas=1;cas<=t;cas++){
       scanf("%d%d",&n,&m);
       cnt=0;
       for(i=1;i<=n;i++){
        for(j=1;j<=m;j++){
            scanf("%d",&mm[i][j]);
            if(i>1){
                edge[cnt].u=(i-1)*m+j;
                edge[cnt].v=(i-1)*m+j-m;
                edge[cnt++].len=abs(mm[i][j]-mm[i-1][j]);
            }
            if(j>1){
                edge[cnt].u=(i-1)*m+j;
                edge[cnt].v=(i-1)*m+j-1;
                edge[cnt++].len=abs(mm[i][j]-mm[i][j-1]);
            }
        }
       }
       //cnt--;
       sort(edge,edge+cnt);
       printf("Case #%d:\n",cas);
       printf("%d\n",solve());
    }
    return 0;
}

 

hdu 5253 连接的管道(百度之星初赛)

标签:

原文地址:http://www.cnblogs.com/dominatingdashuzhilin/p/4845307.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!