洛谷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); }
Copyright:http://www.cnblogs.com/candy99/