您的位置:首页 > 编程语言 > Java开发

poj 3026 Borg Maze(java bfs + prim)

2017-08-19 14:03 357 查看
package prim;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/**问题请参考http://poj.org/problem?id=3026
* @author rayli

* @date:2014-7-28 下午4:07:33
* 题意 :给定一个迷宫,在一个迷宫内,建立一颗最小生成树连接所有点
*通过BFS找到'S'与每个’A'之间的最短路径。然后prim 建立最小生成树。
*
*求 任意两字母间的最短距离 时不能直接用BFS求,

1、必须先把矩阵中每一个允许通行的格看做一个结点(就是在矩阵内所有非#的格都作为图M的一个顶点),
对每一个结点i,分别用BFS求出它到其他所有结点的权值(包括其本身,为0),构造结点图M;

2、然后再加一个判断条件,从图M中抽取以字母为顶点的图,进而构造字母图N

这个判定条件就是当结点图M中的某点j为字母时,把i到j的权值再复制(不是抽离)出来,记录到字母图N的邻接矩阵中

3、剩下的就是对字母图N求最小生成树了
*/

class Node
{//结点
public int x;//x坐标
public int y;//y坐标
// public int w;
}

public class BorgMaze
{
static char map[][];
static Node node[];
static int r;
static int c;
static int num;
int ans;
static int cost[][];

void bfs(Node n)
{
int dir[][] = {{0,1}, {0,-1}, {1,0}, {-1, 0}};//方向
int t[][] = new int[r][c];

//对t进行初始化为-1
for(int i=0; i<r; i++)
for(int j=0; j<c; j++)
t[i][j] = -1;

Queue<Node> q = new LinkedList<Node>();
t[n.x][n.y] = 0;//对开始点进行标记
q.add(n);//加入队列

while(!q.isEmpty())
{
Node cur = q.remove();
int x =0;
int y;

for(int i=0; i<num; i++)//查找始结点在数组中的位置
{
if(n == node[i])
{
x = i;
break;
}
}

for(int j=0; j<num; j++)
{

if((cur.x == node[j].x) && (cur.y == node[j].y))//目前结点在数组中的位置
{
y = j;
cost[x][y] = t[cur.x][cur.y];
break;
}
}

for(int i=0; i<4; i++)//下,上,右,左
{
int tx = cur.x + dir[i][0];
int ty = cur.y + dir[i][1];

Node next = new Node();

if(tx >= 0 && tx < r && ty >=0 && ty < c)
if(map[tx][ty] != '#' && t[tx][ty] < 0)
{
next.x = tx;
next.y = ty;
t[tx][ty] = t[cur.x][cur.y] + 1;
q.add(next);
}
}
}
}

void prim()
{
// boolean vist[][] = new boolean[r][c];
int lowcost[] = new int[num];
ans = 0;

for(int i=1; i<num; i++)
{
lowcost[i] = cost[0][i];
}

for(int i=1; i<num; i++)
{
int minum = Integer.MAX_VALUE;
int tmp = 0;

for(int j=0; j<num; j++)
{
if(lowcost[j] > 0 && minum > lowcost[j])
{
minum = lowcost[j];
tmp = j;
}
}

if(minum != Integer.MAX_VALUE)
ans += minum;

lowcost[tmp] = 0;

for(int j=0; j<num; j++)
{
if(cost[tmp][j] < lowcost[j])
{
lowcost[j] = cost[tmp][j];
}
}

}
}

void output()
{
System.out.println(ans);
}

public static void main(String args[])
{
Scanner cin = new Scanner(System.in);
int n = cin.nextInt();//迷宫数

while(n-->0)
{
c = cin.nextInt();//迷宫列数
r = cin.nextInt();//行数

map = new char[r][c];
node = new Node[102];//用于存储结点A,S

cin.nextLine();
for(int i=0; i<r; i++)
map[i] = cin.nextLine().toCharArray();

BorgMaze bm = new BorgMaze();
num = 0;

for(int i=0; i<r; i++)
for(int j=0; j<c; j++)
{
if(map[i][j] == 'A' || map[i][j] == 'S')
{
Node now = new Node();
now.x = i;
now.y = j;

node[num] = now;
num++;

}
}

cost = new int[num][num];
//对每个结点分别求出它到其他结点的距离
for(int i=0; i<num; i++)
{
bm.bfs(node[i]);
}

//求最小生成树
bm.prim();
bm.output();
}

cin.close();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: