2015百度之星 初赛2 连接的管道 最小生成树
来源:互联网 发布:c语言windows代码 编辑:程序博客网 时间:2024/04/30 03:54
题意:老 Jack 有一片农田,以往几年都是靠天吃饭的。但是今年老天格外的不开眼,大旱。所以老 Jack 决定用管道将他的所有相邻的农田全部都串联起来,这样他就可以从远处引水过来进行灌溉了。当老 Jack 买完所有铺设在每块农田内部的管道的时候,老 Jack 遇到了新的难题,因为每一块农田的地势高度都不同,所以要想将两块农田的管道链接,老 Jack 就需要额外再购进跟这两块农田高度差相等长度的管道。
现在给出老 Jack农田的数据,你需要告诉老 Jack 在保证所有农田全部可连通灌溉的情况下,最少还需要再购进多长的管道。另外,每块农田都是方形等大的,一块农田只能跟它上下左右四块相邻的农田相连通。
思路: 建图,边权值是两点高度之差的绝对值。最小生成树,跑一发克鲁斯卡尔就行了。这题容易爆内存...建图的时候可以只加入单向边以节省空间。
#include <iostream>#include <cstdio>#include <cmath>#include <cstdio>#include <vector>#include <queue>#include <algorithm>#include <cstring>#include <string>#include <cstdlib>#include <map>using namespace std;#define I64_MAX 9223372036854775807 typedef long long ll;const double pi=acos (-1.0);const double eps=1e-8 ;//const ll INF=(I64_MAX)/2;//#pragma comment(linker, "/STACK:102400000,102400000")const int inf=0x3f3f3f3f ;#define maxx(a) memset(a, 0x3f, sizeof(a))#define zero(a) memset(a, 0, sizeof(a))#define FILL(a,b) memset(a, b, sizeof(a))#define REP(i,a,b) for(i=a;i<b;i++)#define rep(i,n) REP(i,0,n)#define srep(i,n) for(i = 1;i <= n;i ++)#define snuke(c,itr) for( __typeof((c).begin()) itr=(c).begin();itr!=(c).end();itr++)#define mp make_pair#define fi first#define se secondtypedef pair <int, int> pii;typedef pair <ll, ll> PX;typedef pair<int,ll> PIL;const int MAXN=1000006;//最大点数const int MAXM=2000006;//最大边数int F[MAXN];//并查集使用struct Edge{int u,v,w;}edge[MAXM];//存储边的信息,包括起点/终点/权值int tol;//边数,加边前赋值为0void addedge(int u,int v,int w){edge[tol].u=u;edge[tol].v=v;edge[tol++].w=w;}bool cmp(Edge a,Edge b){//排序函数,讲边按照权值从小到大排序return a.w<b.w;}int find(int x){if(F[x]==-1)return x;else return F[x]=find(F[x]);}int Kruskal(int n)//传入点数,返回最小生成树的权值,如果不连通返回-1{memset(F,-1,sizeof(F));sort(edge,edge+tol,cmp);int cnt=0;//计算加入的边数int ans=0;for(int i=0;i<tol;i++){int u=edge[i].u;int v=edge[i].v;int w=edge[i].w;int t1=find(u);int t2=find(v);if(t1!=t2){ans+=w;F[t1]=t2;cnt++;}if(cnt==n-1)break;}if(cnt<n-1)return -1;//不连通else return ans;}const int maxn = 1005;int mark[2][maxn];pii d[2];int n,m;inline int cal(int x,int y){return x*m+y;}int main(){int T;scanf("%d",&T);d[0] = mp(0,-1);d[1] = mp(-1,0);for(int t=1;t<=T;t++){scanf("%d%d",&n,&m);tol = 0;for(int i=0;i<n;i++){for(int j=0;j<m;j++){scanf("%d",&mark[i%2][j]);for(int k=0;k<2;k++){int x = i+d[k].fi;int y = j+d[k].se;if(x < 0 || y<0){continue;}int v = abs(mark[i%2][j] - mark[x%2][y]);//printf("%d %d\n",mark[i%2][j],mark[x%2][y]);int u1,u2;u1 = cal(i,j);u2 = cal(x,y); addedge(u1,u2,v);//addedge(u2,u1,v);//printf("u1=%d u2=%d v=%d\n",u1,u2,v);}}}printf("Case #%d:\n%d\n",t,Kruskal(n*m));}return 0;}
0 0
- 2015 百度之星 初赛2 1002 连接的管道(最小生成树)
- 2015百度之星 初赛2 连接的管道 最小生成树
- 【百度之星初赛2】连接的管道(Kruskal最小生成树)
- hdu 5253 连接的管道(kruskal)(2015年百度之星程序设计大赛 - 初赛(2))
- 2015百度之星初赛(二) 连接的管道 1002
- 连接的管道(最小生成树)
- 5253 连接的管道【最小生成树prim+优先队列】
- 连接的管道 HDU 杭电5253 【最小生成树】
- HDOJ 5253 连接的管道(最小生成树--kruskul)
- hdoj--5253--连接的管道(最小生成树)
- 【HDU】5253 - 连接的管道(最小生成树)
- hdu 5253 连接的管道(最小生成树)
- HDOJ 5253 连接的管道(最小生成树)
- HDOJ-----5253连接的管道(最小生成树)
- hdoj 5253 连接的管道 (最小生成树-kruskal)
- (最小生成树 Kruskal)HDU 5253 连接的管道
- HDU 5253 连接的管道(最小生成树)
- hdu 5253 连接的管道 最小生成树
- Numpy学习笔记1-基本类型
- 苹果开发 笔记(33)常用组件笔记
- touch事件的派发与传递
- ITOO之精妙设计(一)——大道至简
- json和jsonp的联系和区别(转载)
- 2015百度之星 初赛2 连接的管道 最小生成树
- 一个c++题目引发的思考
- Web前端开发规范手册
- java中runnable和thread的区别
- C语言知识结构
- String拼接的问题
- Docker解析及轻量级PaaS平台演练(四)--Fig相关介绍
- 仿iOS猎豹垃圾清理(实现原理+源码)
- 评教有感