题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20846

POJ 3026是同样的题,但是内存要求比较严格,并是没有过。。。

对以迷宫形式给定的一些点求最小生成树,不过这里的边并不是抽象的两点间笛卡尔距离,也不是折线距离(迷宫中有障碍),而是需要用四个方向的搜索来求。

用bfs求出任两点间的最短距离后,可用kruscal求出最小生成树。

这次值得一提的是对并查集的一点改造:由于每个顶点由一组(x,y)坐标唯一确定,而并查集的元素应是能用一个整数唯一确定的,所以要将(x,y)坐标的集合映射到整数集合。联想到了最近课内学的信道的“分频复用”,和实时操作系统uCOS-II的任务就绪表的数据结构和算法。于是就有了如下做法,其实很常见了~

x,y坐标范围是[0,50],50<2^6,因此可用一个int型(2^31)的低7位存y坐标,8~14位存x坐标,14<31,一个整型完全可以存下。这样一个点可由一个int型数(低14位)完全确定,并且以每维2^14为size开二维数组vis和dis也可以开下。

经检验这个做法可行,其实就是模仿底层,把基本型当作结构体看待,每位的语义是约定好的,自己编码自己解码~

代码在UVA过了(没限制内存),在POJ上还是MLE,待我好好补一补搜索再来更新吧~

 #include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <stack>
#include <vector>
#include <queue>
using namespace std;
const int MAX_S=;
const int MAX_N=;
struct Point
{
int x,y;
Point(){}
Point(int xx,int yy):x(xx),y(yy){}
}; struct Edge
{
Point u,v;
int w;
}e[MAX_N*MAX_N];
bool cmp(const Edge e1,const Edge e2)
{
return e1.w<e2.w;
} int par[(MAX_S<<)+MAX_S];
void init()
{
memset(par,-,sizeof(par));
}
int find(int x)
{
if(par[x]==-) return x;
return par[x]=find(par[x]);
}
void unite(Point p1,Point p2)
{
int x=(p1.x<<)+p1.y;
int y=(p2.x<<)+p2.y;
x=find(x);
y=find(y);
if(x==y) return ;
par[x]=y;
} bool same(Point p1,Point p2)
{
int x=(p1.x<<)+p1.y;
int y=(p2.x<<)+p2.y;
return find(x)==find(y);
} int T;
int w,h;
int n,m;
char maze[MAX_S][MAX_S];
int dx[]={,,,-},dy[]={,-,,}; typedef pair<Point,int> P;
int vis[MAX_S][MAX_S];
int dis[(MAX_S<<)+MAX_S][(MAX_S<<)+MAX_S]; void bfs(int x,int y)
{
int poi=(x<<)+y;
memset(vis,,sizeof(vis));
queue<P> que;//Point,step
que.push(P(Point(x,y),));
vis[x][y]=;
while(!que.empty())
{
Point p=que.front().first;
int step=que.front().second;
que.pop();
for(int i=;i<;i++)
{
int nx=p.x+dx[i];
int ny=p.y+dy[i];
int npoi=(nx<<)+ny;
if(nx<||ny<||w<=nx||w<=ny||vis[nx][ny]) continue;
if(maze[nx][ny]=='#'){vis[nx][ny]=; continue;}
if(dis[poi][npoi]||poi==npoi) continue;
que.push(P(Point(nx,ny),step+));
vis[nx][ny]=;
if((maze[nx][ny]=='A'||maze[nx][ny]=='S')&&poi!=npoi)
{
e[m].u=Point(x,y);
e[m].v=Point(nx,ny);
dis[npoi][poi]=dis[poi][npoi]=e[m].w=step+;
m++;
}
}
}
} int kruscal()
{
init();
int ans=;
for(int i=;i<m;i++)
{
if(!same(e[i].u,e[i].v))
{
unite(e[i].u,e[i].v);
ans+=e[i].w;
}
}
return ans;
} int main()
{
freopen("3026.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&w,&h);
n=;
getchar();
for(int i=;i<h;i++)
{
fgets(maze[i],w,stdin);
gets(maze[i+]);
}
m=;
memset(dis,,sizeof(dis));
for(int i=;i<h;i++)
{
for(int j=;j<w;j++)
if(maze[i][j]=='A'||maze[i][j]=='S') bfs(i,j);
}
/*
for(int i=0;i<m;i++)
printf("%d %d -> %d %d = %d\n",e[i].u.x,e[i].u.y,e[i].v.x,e[i].v.y,e[i].w);
*/
sort(e,e+m,cmp);
printf("%d\n",kruscal());
}
return ;
}

【UVA 10307 Killing Aliens in Borg Maze】最小生成树, kruscal, bfs的更多相关文章

  1. poj 3026 Borg Maze 最小生成树 + 广搜

    点击打开链接 Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7097   Accepted: 2389 ...

  2. 快速切题 poj 3026 Borg Maze 最小生成树+bfs prim算法 难度:0

    Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8905   Accepted: 2969 Descrip ...

  3. POJ3026:Borg Maze (最小生成树)

    Borg Maze Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18644   Accepted: 5990 题目链接:h ...

  4. (POJ 3026) Borg Maze 最小生成树+bfs

    题目链接:http://poj.org/problem?id=3026. Description The Borg is an immensely powerful race of enhanced ...

  5. poj 3026 Borg Maze (最小生成树+bfs)

    有几个错误,调试了几个小时,样例过后 1Y. 题目:http://poj.org/problem?id=3026 题意:就是让求A们和S的最小生成树 先用bfs找每两点的距离,再建树.没剪枝 63MS ...

  6. POJ3026 Borg Maze(最小生成树)

    题目链接. 题目大意: 任意两点(点表示字母)可以连线,求使所有点连通,且权值和最小. 分析: 第一感觉使3维的BFS.但写着写着,发现不对. 应当用最小生成树解法.把每个字母(即A,或S)看成一个结 ...

  7. POJ 3026 Borg Maze 广搜(BFS)+最小生成树

    题意:从S出发,去抓每一个A,求总路径最短长度.在S点和A点人可以分身成2人,不过一次只能让一个人走. 思路是先利用BFS求出各点之间的距离,建成图,再套用最小生成树模板. 一次性A了.不过觉得在判断 ...

  8. Borg Maze POJ - 3026 (BFS + 最小生成树)

    题意: 求把S和所有的A连贯起来所用的线的最短长度... 这道题..不看discuss我能wa一辈子... 输入有坑... 然后,,,也没什么了...还有注意 一次bfs是可以求当前点到所有点最短距离 ...

  9. Borg Maze - poj 3026(BFS + Kruskal 算法)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9821   Accepted: 3283 Description The B ...

随机推荐

  1. 解决问题之,wp项目中使用MatchCollection正则表达式匹配出错

    在最近,出现了这么一个问题 本人使用正则表达式代码,解析响应output,意图获得周边的CMCC热点 代码如下: //output="<?xml version=\"1.0\ ...

  2. UML_活动图

    一.活动图的组成元素 Activity Diagram Element 1.活动状态图(Activity) 2.动作状态(Actions) 3.动作状态约束(Action Constraints) 4 ...

  3. 【转】Android LCD(二):LCD常用接口原理篇

    关键词:android LCD TFT TTL(RGB)  LVDS  EDP MIPI  TTL-LVDS  TTL-EDP 平台信息:内核:linux2.6/linux3.0系统:android/ ...

  4. Mac 下纯lua(三)

    文件处理 直接使用io调用 io.close();文件流关闭 io.flush():如果文件流以bufferd缓存模式处理,输入不会立即存入文件,需要调用本函数 io.input(file):输入 i ...

  5. 解决红米等手机(移动端)无法触发touchend事件

    触屏事件的简单描述: js的触屏事件,主要有三个事件:touchstart,touchmove,touchend. 这三个事件最重要的属性是 pageX和 pageY,表示X坐标,Y坐标.touchs ...

  6. SPOJ GCDEX (数论)

    转载请注明出处,谢谢http://blog.csdn.net/ACM_cxlove?viewmode=contents    by---cxlove 题意:求sigma (gcd (i , j))  ...

  7. 【git学习二】git基础之git管理本地项目

    1.背景        git基础打算分两部分来说,一部分是对于本地项目的管理,第二部分是对于远程代码仓库的操作. git运行本地项目管理包含对于相关文件的追踪,暂存区的比較分析,提交,撤销等功能. ...

  8. LoadRunner如何在注册业务脚本中设置参数化唯一性

    LR在录制一个网站注册业务的脚本时,突然间遇到一个问题:注册时,由于注册用户需要验证唯一性,所以在LR回放脚本时,用Run-time Viewer工具回放可以发现(先在脚本中设置几个断点),真实运行的 ...

  9. CSS清除浮动_清除float浮动

    2.clear:both清除浮动为了统一样式,我们新建一个样式选择器CSS命名为“.clear”,并且对应选择器样式为“clear:both”,然后我们在父级“</div>”结束前加此di ...

  10. 【巧妙预处理系列】【UVA1330】City game

    最大子矩阵(City Game, SEERC 2004, LA 3029) 给定一个m×n的矩阵,其中一些格子是空地(F),其他是障碍(R).找出一个全部由F组成的面积最大的子矩阵,输出其面积乘以3后 ...