您的位置:首页 > 其它

poj 3026 BFS + prim(最短路最小生成树的区别)

2016-08-07 13:10 537 查看
Borg Maze

Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 12909 Accepted: 4206
Description
The Borg is an immensely powerful race of enhanced humanoids from the delta quadrant of the galaxy. The Borg collective is the term used to describe the group consciousness of the Borg civilization. Each Borg individual is linked
to the collective by a sophisticated subspace network that insures each member is given constant supervision and guidance.

Your task is to help the Borg (yes, really) by developing a program which helps the Borg to estimate the minimal cost of scanning a maze for the assimilation of aliens hiding in the maze, by moving in north, west, east, and south steps. The tricky thing is
that the beginning of the search is conducted by a large group of over 100 individuals. Whenever an alien is assimilated, or at the beginning of the search, the group may split in two or more groups (but their consciousness is still collective.). The cost
of searching a maze is definied as the total distance covered by all the groups involved in the search together. That is, if the original group walks five steps, then splits into two groups each walking three steps, the total distance is 11=5+3+3.

Input
On the first line of input there is one integer, N <= 50, giving the number of test cases in the input. Each test case starts with a line containg two integers x, y such that 1 <= x,y <= 50. After this, y lines follow, each which
x characters. For each character, a space `` '' stands for an open space, a hash mark ``#'' stands for an obstructing wall, the capital letter ``A'' stand for an alien, and the capital letter ``S'' stands for the start of the search. The perimeter of the maze
is always closed, i.e., there is no way to get out from the coordinate of the ``S''. At most 100 aliens are present in the maze, and everyone is reachable.

Output
For every test case, output one line containing the minimal cost of a succesful search of the maze leaving no aliens alive.

Sample Input
2
6 5
#####
#A#A##
# # A#
#S  ##
#####
7 7
#####
#AAA###
#    A#
# S ###
#     #
#AAA###
#####

Sample Output
8
11


题意:

求连接所有字母的最短路径

题解:

因为要求最段路径,使用prim,而使用prim需要知道每一个字母与其他字母的的路径权值

然后我们就开始求权值

求权值通过BFS

这里的BFS的使用:

找到所有的字母,然后从每一个字母开始BFS,记录字母到其他字母的权值

关键是这里需要先把空格也看做节点,然后再剔除空格,就是所求的权值了

注意:

使用prim的时候不要习惯性打个n进去,因为这里并不是N个字母

下面注释的地方都是出过问题的地方,切记

然后map数组全部初始化为 -1 ,这里需要理解(只是标记有没有走过,起始地初始化为 0 了,然后从这个0 持续边走边加)

然后平时学习需要多复习,这个prim有点遗忘了,还有点和dijkstra搞混了

最小生成树 和 最短路径 的区别:

最小生成树    是保证无向图每两点间可以互相到达,并且边权之和最小(遍历整个图的)

最短路径        是保证起点可到达终点(有向图中不要求终点能到起点),并且路径权值之和最小

最小生成树    没有保证路径最小...形象点就是 最小生成树只和马路长度有关

最短路径        要考虑你一条马路走了几次

最小生成树可能有多个,只是保证树的所有权总和最小并且包括所有点

#include<queue>
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

#define INF 0x3f3f3f3f
#define M 300

int n,m;
char a[M][M];
int v[M][M];

int dx[5]={0,0,1,-1};
int dy[5]={-1,1,0,0};

struct node
{
int x,y;
};

int map[M][M];
int sum[500][500];
void BFS(int sx,int sy)
{
node start;
start.x=sx;start.y=sy;

queue<node>q;
while(q.size())
q.pop();

q.push(start);

memset(map,-1,sizeof(map));
map[sx][sy]=0;

while(!q.empty())
{
node temp=q.front();
q.pop();
if(v[temp.x][temp.y]!=-1)//记录两个字母之间的权值
sum[v[sx][sy]][v[temp.x][temp.y]]=map[temp.x][temp.y];

node t;
for(int i=0;i<4;i++){
t.x=temp.x+dx[i];
t.y=temp.y+dy[i];

if(a[t.x][t.y]!='#'&&(map[t.x][t.y]==-1)){
q.push(t);
map[t.x][t.y]=map[temp.x][temp.y]+1;
}
}
}
}

int index;//多少个字母需要连接
int dis[500];
int prim()
{
int ans=0,pos=1;
int min_weight,p;
memset(dis,INF,sizeof(dis));

for(int i=1;i<index;i++){
dis[pos]=-1;
min_weight=INF;

for(int j=1;j<=index;j++){
if(dis[j]>=0&&sum[pos][j]){
dis[j]=dis[j]<sum[pos][j]?dis[j]:sum[pos][j];

if(dis[j]<min_weight){
min_weight=dis[j];
p=j;
}
}
}
pos=p;
ans+=min_weight;
}
return ans;
}

int main()
{
int T;
//freopen("in.txt","r",stdin);
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&m);
gets(a[0]);
index=1;
memset(v,-1,sizeof(v));
memset(sum,0,sizeof(sum));
for(int i=0;i<m;i++){
gets(a[i]);
for(int j=0;j<n;j++)
if(a[i][j]=='A'||a[i][j]=='S')
v[i][j]=index++;
}

index--;
for(int i=0;i<n;i++)
for(int j=0;j<n;j++)
if(v[i][j]!=-1)
BFS(i,j);

printf("%d\n",prim());
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: