图练习与答案Word格式文档下载.docx
《图练习与答案Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《图练习与答案Word格式文档下载.docx(13页珍藏版)》请在冰豆网上搜索。
2
3
4
5
6
7
8
U
V.-U
Vex
Lowcost
7.已知世界六大城市为:
北京(Pe)、纽约(N)、巴黎(Pa)、伦敦(L)、东京(T)、墨西哥(M),下表给定了这六大城市之间的交通里程:
世界六大城市交通里程表(单位:
百公里)
pe
n
pa
L
T
M
Pe
109
82
81
21
124
N
58
55
108
32
PA
97
92
95
89
113
(1).画出这六大城市的交通网络图;
(2).画出该图的邻接表表示法;
(3).画出该图按权值递增的顺序来构造的最小(代价)生成树.
8.已知顶点1-6和输入边与权值的序列(如右图所示):
每行三个数表示一条边
的两个端点和其权值,共11行。
请你:
(1).采用邻接多重表表示该无向网,用类PASCAL语言描述该数据结构,画出存
储结构示意图,要求符合在边结点链表头部插入的算法和输入序列的次序。
(2).分别写出从顶点1出发的深度优先和广度优先遍历顶点序列,以及相应的
生成树。
(3).按prim算法列表计算,从顶点1始求最小生成树,并图示该树。
125
138
143
246
232
344
351
3610
457
4611
5615
9.用最短路径算法,求如下图中a到z的最短通路。
【
(4).由顶点V1到顶点V3的最短路径。
【中山大学1994四(12分)】
题
10.已知图的邻接矩阵为:
V1
V2
V3
V4
V5
V6
V7
V8
V9
V10
1
当用邻接表作为图的存储结构,且邻接表都按序号从大到小排序时,试写出:
(1).以顶点V1为出发点的唯一的深度优先遍历;
(2).以顶点V1为出发点的唯一的广度优先遍历;
(3).该图唯一的拓扑有序序列。
11.已知一图如下图所示:
(1).写出该图的邻接矩阵;
(2).写出全部拓扑排序;
(3).以v1为源点,以v8为终点,给出所有事件允许发生的最早时间和最晚时间,并给出关键路径;
(4).求V1结点到各点的最短距离。
12.
(1).对于有向无环图,叙述求拓扑有序序列的步骤;
(2).对于以下的图,写出它的四个不同的拓扑有序序列。
二.算法设计题
1.设无向图G有n个顶点,m条边。
试编写用邻接表存储该图的算法。
(设顶点值用1~n或0~n-1编号)
答:
voidCreatGraph(AdjListg)
//建立有n个顶点和m条边的无向图的邻接表存储结构
{intn,m;
scanf("
%d%d"
&
n,&
m);
for(i=1,i<
=n;
i++)//输入顶点信息,建立顶点向量
{scanf(&
g[i].vertex);
g[i].firstarc=null;
}
for(k=1;
k<
=m;
k++)//输入边信息
{scanf(&
v1,&
v2);
//输入两个顶点
i=GraphLocateVertex(g,v1);
j=GraphLocateVertex(g,v2);
//顶点定位
p=(ArcNode*)malloc(sizeof(ArcNode));
//申请边结点
p->
adjvex=j;
p->
next=g[i].firstarc;
g[i].firstarc=p;
//将边结点链入
p=(ArcNode*)malloc(sizeof(ArcNode));
adjvex=i;
next=g[j].firstarc;
g[j].frstarc=p;
}
}//算法CreatGraph结束
2.请用流程图或类高级语言(c)表示算法。
已知有向图有n个顶点,请写算法,根据用户输入的偶对建立该有向图的邻接表。
即接受用户输入的<
vi,vj>
(以其中之一为0标志结束),对于每条这样的边,申请一个结点,并插入到的单链表中,如此反复,直到将图中所有边处理完毕。
提示:
先产生邻接表的n个头结点(其结点数值域从1到n)。
答.
voidCreatAdjList(AdjListg)
//建立有向图的邻接表存储结构
{intn;
scanf("
%d"
n);
for(i=1;
i<
j++)
}//输入顶点信息
scanf(&
v1,.&
while(v1&
&
v2)//题目要求两顶点之一为0表示结束
{i=GraphLocateVertex(g2,v1);
p=(ArcNode*)malloc(sizeof(ArcNode));
p->
}}
3.设有向G图有n个点(用1,2,…,n表示),e条边,写一算法根据其邻接表生成其反向邻接表,要求算法复杂性为O(n+e)。
voidInvertAdjList(AdjListgin,gout)
//将有向图的出度邻接表改为按入度建立的逆邻接表
{for(i=1;
i++)//设有向图有n个顶点,建逆邻接表的顶点向量。
{gin[i].vertex=gout[i].vertex;
gin.firstarc=null;
for(i=1;
i++)//邻接表转为逆邻接表。
{p=gout[i].firstarc;
//取指向邻接表的指针。
while(p!
=null)
{j=p->
adjvex;
s=(ArcNode*)malloc(sizeof(ArcNode));
//申请结点空间。
s->
next=gin[j].firstarc;
gin[j].firstarc=s;
p=p->
next;
//下一个邻接点。
}//while
}//for}
4.试写一算法,判断以邻接表方式存储的有向图中是否存在由顶点Vi到顶点Vj的路径(i<
>
j)。
注意:
算法中涉及的图的基本操作必须在存储结构上实现。
答.[题目分析]在有向图中,判断顶点Vi和顶点Vj间是否有路径,可采用遍历的方法,从顶点Vi出发,不论是深度优先遍历(dfs)还是宽度优先遍历(bfs),在未退出dfs或bfs前,若访问到Vj,则说明有通路,否则无通路。
设一全程变量flag。
初始化为0,若有通路,则flag=1。
intvisited[]=0;
//全局变量,访问数组初始化
intdfs(AdjListg,vi)
//以邻接表为存储结构的有向图g,判断顶点Vi到Vj是否有通路,返回1或0表示有或无
{visited[vi]=1;
//visited是访问数组,设顶点的信息就是顶点编号。
p=g[vi].firstarc;
//第一个邻接点。
while(p!
if(vj==j){flag=1;
return
(1);
}//vi和vj有通路。
if(visited[j]==0)dfs(g,j);
next;
}//while
if(!
flag)return(0);
}//结束
5.设有向图用邻接表表示,图有n个顶点,表示为1至n,试写一个算法求顶点k的入度(1<
n)。
答.[题目分析]在有向图的邻接表中,求顶点的出度容易,只要简单在该顶点的邻接点链表中查结点个数即可。
而求顶点的入度,则要遍历整个邻接表。
intcount(AdjListg,intk)
//在n个顶点以邻接表表示的有向图g中,求指定顶点k(1<
=k<
=n)的入度。
{intcount=0;
i++)//求顶点k的入度要遍历整个邻接表。
if(i!
=k)//顶点k的邻接链表不必计算
{p=g[i].firstarc;
//取顶点i的邻接表。
while(p)
{if(p->
adjvex==k)count++;
}//while
}//if
return(count);
//顶点k的入度.
6.试编写求无向图G的连通分量的算法。
要求输出每一连通分量的顶点值。
(设图G已用邻接表存储)
答.[题目分析]使用图的遍历可以求出图的连通分量。
进入dfs或bfs一次,就可以访问到图的一个连通分量的所有顶点。
voiddfs()
{visited[v]=1;
printf(“%3d”,v);
//输出连通分量的顶点。
p=g[v].firstarc;
while(p!
{if(visited[p->
adjvex==0])dfs(p->
adjvex);
}//dfs
voidCount()
//求图中连通分量的个数
{intk=0;
staticAdjListg;
//设无向图g有n个结点
i++)
if(visited[i]==0){printf("
\n第%d个连通分量:
\n"
++k);
dfs(i);
}//Count
算法中visited[]数组是全程变量,每个连通分量的顶点集按遍历顺序输出。
这里设顶点信息就是顶点编号,否则应取其g[i].vertex分量输出。
7.写出图的深度优先搜索DFS算法的非递归算法。
答.voidTraver(AdjListg,vertypev)
//图g以邻接表为存储结构,算法从顶点v开始实现非递归深度优先遍历。
{structarc*stack[];
visited[v]=1;
printf(v);
//输出顶点v
top=0;
p=g[v].firstarc;
stack[++top]=p;
while(top>
0||p!
{while(p)
if(p&
visited[p->
adjvex])p=p->
else{printf(p->
adjvex]=1;
stack[++top]=p;
p=g[p->
adjvex].firstarc;
}//else
if(top>
0){p=stack[top--];
}//while}//算法结束。
[算法讨论]以上算法适合连通图,若是非连通图,则再增加一个主调算法,其核心语句是for(vi=1;
vi<
vi++)if(!
visited[vi])Traver(g,vi);
8.已知个n顶点的有向图,用邻接矩阵表示,编写函数计算每对顶点的最短路径。
答.
本题用FLOYD算法直接求解如下:
voidShortPath_FLOYD(AdjMatrixg)
//求具有n个顶点的有向图每对顶点间的最短路径
{AdjMatrixlength;
//length[i][j]存放顶点vi到vj的最短路径长度。
i++)
for(j=1;
j<
j++)length[i][j]=g[i][j];
//初始化。
for(k=1;
k++)
if(length[i][k]+length[k][j]<
length[i][j])
length[i][j]=length[i][k]+length[k][j];
}//算法结束
9.欲用四种颜色对地图上的国家涂色,有相邻边界的国家不能用同一种颜色(点相交不算相邻)。
(1).试用一种数据结构表示地图上各国相邻的关系,(6分)。
(2).描述涂色过程的算法。
(不要求证明)(12分)。
【浙江大学2002八(18分)】
答.[题目分析]地图涂色问题可以用“四染色“定理。
将地图上的国家编号(1到n),从编号1开始逐一涂色,对每个区域用1色,2色,3色,4色(下称“色数”)依次试探,若当前所取颜色与周围已涂色区域不重色,则将该区域颜色进栈;
否则,用下一颜色。
若1至4色均与相邻某区域重色,则需退栈回溯,修改栈顶区域的颜色。
用邻接矩阵数据结构C[n][n]描叙地图上国家间的关系。
n个国家用n阶方阵表示,若第i个国家与第j个国家相邻,则Cij=1,否则Cij=0。
用栈s记录染色结果,栈的下标值为区域号,元素值是色数。
voidMapColor(AdjMatrixC)
//以邻接矩阵C表示的n个国家的地区涂色
{ints[];
//栈的下标是国家编号,内容是色数
s[1]=1;
//编号01的国家涂1色
i=2;
j=1;
//i为国家号,j为涂色号
while(i<
=n)
{while(j<
=4&
i<
{k=1;
//k指已涂色区域号
while(k<
i&
s[k]*C[i][k]!
=j)k++;
//判相邻区是否已涂色
if(k<
i)j=j+1;
//用j+1色继续试探
else{s[i]=j;
i++;
}//与相邻区不重色,涂色结果进栈,继续对下一区涂色进行试探
}//while(j<
if(j>
4){i--;
j=s[i]+1;
}//变更栈顶区域的颜色。
}//while}//结束MapColor