您的位置:首页 > 其它

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

2016-09-30 23:51 197 查看

题目背景

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

;
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);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: