算法设计与分析分支界限法实验报告文档格式.docx
《算法设计与分析分支界限法实验报告文档格式.docx》由会员分享,可在线阅读,更多相关《算法设计与分析分支界限法实验报告文档格式.docx(13页珍藏版)》请在冰豆网上搜索。
[SampleInput]
7
dashenOparinToropov
AyzenshteynOparinSamsonov
AyzenshteynChevdarSamsonov
FominykhdashenOparin
DublennykhFominykhIvankov
BurmistrovDublennykhKurpilyanskiy
CormenLeisersonRivest
[SampleOutput]
Ayzenshteyn2
Burmistrov3
Chevdar3
Cormenundefined
Dublennykh2
Fominykh1
dashen0
Ivankov2
Kurpilyanskiy3
Leisersonundefined
Oparin1
Rivestundefined
Samsonov2
Toropov1
实验目的
1)掌握学习什么是分支界限法。
2)掌握学习BFS(宽度优先搜索)的思想过程以及编码实现。
3)掌握学习简单的BFS题目如何去思考并解决实施。
4)学习培养基础的快速变成能力、独立思考恩能够立与解决bug的能力。
实验过程和步骤
1.2解题思路
迷宫搜索最短路径,主要考察的就是最简单裸的BFS。
BFS只要掌握如何标记好数组、边界的考虑、出队进队就好了。
如何保存搜索的层数?
每一次节点扩散层,标记的层数值都是当前层的+1即可。
至于写BFS的写法。
步骤都是一样的:
放第一个进队,然后出队、扩散开进队并标记、出队......循环下去直到队空。
写法太基础就不讲解了。
1.2测试样例
32
46
..#....
..##...
....#..
...##..
#...#..
###....
1.3程序运行情况
1.4程序源码(含注释)
#include"
bits/stdc++.h"
usingnamespacestd;
#defineinf999
intn;
//行数
intsx,sy;
//起点
intgx,gy;
//终点
chare[inf][inf];
//地图
intbook[inf][inf];
//标记地图
intpos[4][2]={-1,0,1,0,0,1,0,-1};
//方位,上下右左
voidread()//输入数据
{
printf("
inputtherowofthemap:
"
);
scanf("
%d"
&
n);
nowinputthepoint:
\n"
%d%d%d%d"
sx,&
sy,&
gx,&
gy);
//输入下标自1开始
sx--;
//计算下标从0开始
sy--;
gx--;
gy--;
inputthemapnow:
for(inti=0;
i<
n;
i++)
%s"
e[i]);
memset(book,0,sizeofbook);
//初始化
}
structNode//节点
intx,y;
Node(inti,intj):
x(i),y(j)
{
}
};
boolislegal(intx,inty)//判断是否合法
if(x<
0||x>
=n||y<
0||y>
=n)returnfalse;
returntrue;
voidbfs()//方便快捷
queue<
Node>
q;
while(!
q.empty())q.pop();
q.push(Node(sx,sy));
//放入首节点
book[sx][sy]=0;
//标记
q.empty())
Nodet=q.front();
q.pop();
//取出节点
inttag=book[t.x][t.y];
if(t.x==gx&
&
t.y==gy)break;
//提前结束
4;
intx=t.x+pos[i][0];
inty=t.y+pos[i][1];
if(islegal(x,y)&
e[x][y]=='
.'
!
book[x][y])//放入未越界、可走、未走过的
q.push(Node(x,y));
book[x][y]=tag+1;
voidoutput()
---------------------\n"
inti,j;
for(i=0;
for(j=0;
j<
j++)
%d"
book[i][j]);
intmain()
read();
//输入
bfs();
output();
//输出
return0;
2树上最短路径
2.1解题思路
问题问每个人和dashen的距离,组员的距离为1。
也就是说,人与人之间的距离都是通过“组员”来不断量化的。
那么可以想到,组员之间可以画一条边,问题问的整个人际之间的图建好之后,将人看为节点,求出每个节点与某个定点的最短距离。
这个图的遍历+定点最短距离问题显然用BFS很好解决。
问题的难点:
1)映射字符串到id的关系,我用的是STL的map容器解决。
2)保存点之间边的关系,本来用的是矩阵保存,但是写到后来很麻烦,就用邻接表保存
3)输出的时候有点麻烦
2.2测试样例
2.3程序运行情况
2.4程序源码(含注释)
#defineINF999999999
intn,num;
//行数,以及不重复人数
intorigin;
//起点,即dashen的标号
intbook[inf];
vector<
int>
edge[inf];
//每个点的边集
structStudent{//学生类,下标自1始
stringname;
intid;
intrank;
voidset(strings,inti)
name=s;
id=i;
rank=INF;
//所有人的距离默认无穷大
booloperator<
(constStudent&
t)const
name<
t.name;
}student[inf];
num=0;
//人数初始化
//初始化标记
cout<
<
inputthenumofthegroups:
;
cin>
>
nowinputtheeachgroupmates:
map<
string,int>
m;
m.clear();
strings[3];
//临时存放
for(intj=0;
3;
j++)//读入点,建点
s[j];
if(m[s[j]]==0)//没出现过就赋予标号以及存储名字
m[s[j]]=++num;
student[num].set(s[j],num);
//存储此人id和名字
if(s[j]=="
dashen"
)
origin=m[s[j]];
2;
j++)//建图
for(intk=j+1;
k<
k++)
inta=m[s[j]];
intb=m[s[k]];
edge[a].push_back(b);
//加入边集
edge[b].push_back(a);
voidbfs()//根据id进行bfs
q.push(origin);
book[origin]=1;
//标记走过
student[origin].rank=0;
//dashen是0
intv=q.front();
intlen=edge[v].size();
len;
intu=edge[v][i];
student[u].rank=min(student[v].rank+1,student[u].rank);
if(!
book[u])
q.push(u);
book[u]=1;
inti;
sort(student+1,student+num+1);
//排序
for(i=1;
=num;
student[i].name<
"
intid=student[i].id;
if(student[i].rank==INF)
undefined"
endl;
else
student[i].rank<