hdu 5253 连接的管道 简单MST

题目链接



解法: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])

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值