【UVA 10307 Killing Aliens in Borg Maze】最小生成树, kruscal, bfs

题目链接: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,待我好好补一补搜索再来更新吧~

  1 #include <cstdio>
  2 #include <cstring>
  3 #include <cmath>
  4 #include <algorithm>
  5 #include <stack>
  6 #include <vector>
  7 #include <queue>
  8 using namespace std;
  9 const int MAX_S=55;
 10 const int MAX_N=105;
 11 struct Point
 12 {
 13     int x,y;
 14     Point(){}
 15     Point(int xx,int yy):x(xx),y(yy){}
 16 };
 17
 18 struct Edge
 19 {
 20     Point u,v;
 21     int w;
 22 }e[MAX_N*MAX_N];
 23 bool cmp(const Edge e1,const Edge e2)
 24 {
 25     return e1.w<e2.w;
 26 }
 27
 28 int par[(MAX_S<<7)+MAX_S];
 29 void init()
 30 {
 31     memset(par,-1,sizeof(par));
 32 }
 33 int find(int x)
 34 {
 35     if(par[x]==-1) return x;
 36     return par[x]=find(par[x]);
 37 }
 38 void unite(Point p1,Point p2)
 39 {
 40     int x=(p1.x<<7)+p1.y;
 41     int y=(p2.x<<7)+p2.y;
 42     x=find(x);
 43     y=find(y);
 44     if(x==y) return ;
 45     par[x]=y;
 46 }
 47
 48 bool same(Point p1,Point p2)
 49 {
 50     int x=(p1.x<<7)+p1.y;
 51     int y=(p2.x<<7)+p2.y;
 52     return find(x)==find(y);
 53 }
 54
 55 int T;
 56 int w,h;
 57 int n,m;
 58 char maze[MAX_S][MAX_S];
 59 int dx[]={0,0,1,-1},dy[]={1,-1,0,0};
 60
 61 typedef pair<Point,int> P;
 62 int vis[MAX_S][MAX_S];
 63 int dis[(MAX_S<<7)+MAX_S][(MAX_S<<7)+MAX_S];
 64
 65 void bfs(int x,int y)
 66 {
 67     int poi=(x<<7)+y;
 68     memset(vis,0,sizeof(vis));
 69     queue<P> que;//Point,step
 70     que.push(P(Point(x,y),0));
 71     vis[x][y]=1;
 72     while(!que.empty())
 73     {
 74         Point p=que.front().first;
 75         int step=que.front().second;
 76         que.pop();
 77         for(int i=0;i<4;i++)
 78         {
 79             int nx=p.x+dx[i];
 80             int ny=p.y+dy[i];
 81             int npoi=(nx<<7)+ny;
 82             if(nx<0||ny<0||w<=nx||w<=ny||vis[nx][ny]) continue;
 83             if(maze[nx][ny]=='#'){vis[nx][ny]=1; continue;}
 84             if(dis[poi][npoi]||poi==npoi) continue;
 85             que.push(P(Point(nx,ny),step+1));
 86             vis[nx][ny]=1;
 87             if((maze[nx][ny]=='A'||maze[nx][ny]=='S')&&poi!=npoi)
 88             {
 89                 e[m].u=Point(x,y);
 90                 e[m].v=Point(nx,ny);
 91                 dis[npoi][poi]=dis[poi][npoi]=e[m].w=step+1;
 92                 m++;
 93             }
 94         }
 95     }
 96 }
 97
 98 int kruscal()
 99 {
100     init();
101     int ans=0;
102     for(int i=0;i<m;i++)
103     {
104         if(!same(e[i].u,e[i].v))
105         {
106             unite(e[i].u,e[i].v);
107             ans+=e[i].w;
108         }
109     }
110     return ans;
111 }
112
113 int main()
114 {
115     freopen("3026.txt","r",stdin);
116     scanf("%d",&T);
117     while(T--)
118     {
119         scanf("%d%d",&w,&h);
120         n=0;
121         getchar();
122         for(int i=0;i<h;i++)
123         {
124             fgets(maze[i],w,stdin);
125             gets(maze[i+1]);
126         }
127         m=0;
128         memset(dis,0,sizeof(dis));
129         for(int i=0;i<h;i++)
130         {
131             for(int j=0;j<w;j++)
132                 if(maze[i][j]=='A'||maze[i][j]=='S') bfs(i,j);
133         }
134 /*
135        for(int i=0;i<m;i++)
136            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);
137 */
138         sort(e,e+m,cmp);
139         printf("%d\n",kruscal());
140     }
141     return 0;
142 }

 

时间: 2024-11-01 01:40:53

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

POJ 3206 Borg Maze:BFS+Prim

Borg Maze:http://poj.org/problem?id=3026 大意:给你一个m*n的迷宫,可以上下左右的走,只能走空格或字母,求出将所有字母连通起来的最小耗费. 思路:先用BFS求出S到所有A的距离,再用Prim求最小生成树,求出最小耗费.这个题坑的不在题,是数据太坑了,在空格处理上没弄好,贡献了好几个WA和CE,看Discuss才知道很坑,最后用G++过了的代码,C++还RE,实在不知道说什么好了  =.= 更多精彩内容:http://www.bianceng.cnhttp

poj 3206 Borg Maze MST

    很无聊的题目,先bfs求下最短,再prim,输入还有多余空格--懒得敲了,随便找了个代码. 以下代码从http://hi.baidu.com/00gfzs/item/6dd7bf221b955c404799624a转载 #include <iostream> #include <queue> #include <cstring> #include <cstdio> using namespace std; int Val[102]; //prim记录

UVa 10034:Freckles (最小生成树模板题)

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=975 题目: Problem A: Freckles In an episode of the Dick Van Dyke show, little Richie connects the freckles on his Dad's back to fo

迷宫求解非递归 DFS BFS(应用栈和队列)

栈和队列的应用对迷宫问题求解 没有递归 自己手动建的栈和队 并且输出路径 DFS的路径就是 栈中的坐标 BFS的路径在队又开了一个域存上一层的base值 语言还是用的C++ 感觉比C的封装性好很多 充分体会了一下DFS一边比BFS快 但是BFS是最优解而DFS可能不是最优解   #include <iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace

UVa 10397:Connect the Campus (最小生成树)

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1338 题目: Problem E Connect the Campus Input: standard input Output: standard output Time Limit: 2 seconds Many new buildings are

UVa 10369:Arctic Network(求最小生成树的第k小边)

链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=24&page=show_problem&problem=1310 题目: Problem C: Arctic Network The Department of National Defence (DND) wishes to connect several northern outposts by a wir

UVa 705:Slash Maze, 斜线迷宫

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105&page=show_problem&problem=646 题目类型: 搜索 题目: By filling a rectangle with slashes (/) and backslashes ( ), you can generate nice little mazes. Here is an

UVa 784:Maze Exploration 搜索专题

题目链接: http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=105&page=show_problem&problem=725 题目类型: 搜索 样例输入: 2 XXXXXXXXX X X X X * X X X X XXXXXXXXX X X X X X X XXXXX _____ XXXXX X X X * X X X XXXXX _____ 样例输出: XXXX

uva 784 - Maze Exploration

点击打开链接 题目意思:给定一个房间,房间四周都是封闭的,但是房间里面会有相通的门,开始里面有个点要求从这个点开始能够填到的地方全部标记为#,包括自己,输出填充后的房间地图 解题思路:简单的floodfill思路,利用dfs就可以做,从起点开始递归搜索,注意输入的格式 代码: #include <iostream> #include <queue> #include <cstdio> #include <cstring> #include <algor