洛谷U4807抽水机[最小生成树]

题目背景

kkk被Farmer John和他的奶牛贝茜虐的很惨,然后她也想体验下一个Farmer的生活。但她又懒得种地,就选择养鱼。

题目描述

这些鱼都是热带鱼(废话),很娇贵(比kkk娇贵),要经常换水,要不然每当kkk走过来的时候鱼们就会一起使劲拍尾巴导致kkk并不情愿的洗个冷水澡(别问我热带鱼为毛这么机智)。但kkk并不勤快,他只想花费最少的力气以实现换水。

kkk的鱼塘可以分成n*n个独立小池,每两个相邻的小池间都有一个水闸控制水位。开启一个水闸需要花费的力气是这两个相邻的小池的水位之差。已知各个小池的水位,kkk想知道她要给每个小池都换水至少需要多少力气。

输入输出格式

输入格式:

 

第一行一个整数n

接下来n*n个数表示各个小池的水位

 

输出格式:

 

最小力气

 

输入输出样例

输入样例#1:
3
1 2 3
4 5 6
7 8 9
输出样例#1:
12

说明

1<=n<=100

1<=水位<=100


 

题目不清楚,水闸同时打开,要不然还得考虑连通器原理

裸的最小生成树

注意数组开多大,因为这个WA好几次,最后只有81分了,导致比赛与第一无缘

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=105;
inline int read(){
    char c=getchar();int x=0,f=1;
    while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
    return x;
}
int n,m,a[N][N];
inline int id(int i,int j){return (i-1)*n+j;}
struct edge{
    int u,v,w;
    bool operator <(const edge &rhs)const{return w<rhs.w;}
}e[N*(N-1)*2];
int cnt=0;
inline void ins(int u,int v,int w){
    cnt++;
    e[cnt].u=u;e[cnt].v=v;e[cnt].w=w;
}
int fa[N*N];
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
long long kruskal(){
    n*=n;
    sort(e+1,e+1+cnt);
    long long ans=0,num=0;
    for(int i=1;i<=n;i++) fa[i]=i;
    for(int i=1;i<=cnt;i++){
        int u=e[i].u,v=e[i].v;
        int x=find(u),y=find(v);
        if(x!=y){
            ans+=e[i].w;
            fa[x]=y;
            if(++num==n-1) break;
        }
    }
    return ans;
}
int main(){
    n=read();
    m=2*n*(n-1);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=n;j++){
            a[i][j]=read();
            //a[i][j]=i+j;
            if(j!=1) ins(id(i,j),id(i,j-1),abs(a[i][j]-a[i][j-1]) );
            if(i!=1) ins(id(i,j),id(i-1,j),abs(a[i][j]-a[i-1][j]) );
        }
    cout<<kruskal();
    //printf("%d %d",m,cnt);
}

 

posted @ 2016-09-30 23:51  Candy?  阅读(241)  评论(0编辑  收藏  举报