第5课 图101106(6)

2018-11-27 16:43

void SpnTree (AdjList g)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。 {

typedef struct {int i,j,w}node; //设顶点信息就是顶点编号,权是整型数 node edge[];

scanf( \输入边数和顶点数。 for (i=1;i<=e;i++) //输入e条边:顶点,权值。

scanf(\

for (i=2;i<=e;i++) //按边上的权值大小,对边进行逆序排序。 {edge[0]=edge[i]; j=i-1;

while (edge[j].w

k=1; eg=e;

while (eg>=n) //破圈,直到边数e=n-1. {if (connect(k)) //删除第k条边若仍连通。

{edge[k].w=0; eg--; }//测试下一条边edge[k],权值置0表示该边被删除 k++; //下条边 }//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,若是连通图,一次进入dfs或bfs就可遍历完全部结点,否则,因为删除该边而使原连通图成为两个连通分量时,该边不应删除。前面第17,18题就是测连通分量个数的算法,请参考。“破圈”结束后,可输出edge中w不为0的n-1条边。

18.已知个n顶点的有向图,用邻接矩阵表示,编写函数计算每对顶点的最短路径。 参考答案:

本题用FLOYD算法直接求解如下: void ShortPath_FLOYD(AdjMatrix g)

//求具有n个顶点的有向图每对顶点间的最短路径

{AdjMatrix length; //length[i][j]存放顶点vi到vj的最短路径长度。 for (i=1;i<=n;i++)

for (j=1;j<=n;j++) length[i][j]=g[i][j]; //初始化。 for (k=1;k<=n;k++) for (i=1;i<=n;i++)

for (j=1;j<=n;j++)

if (length[i][k]+length[k][j]

length[i][j]=length[i][k]+length[k][j]; }

19.欲用四种颜色对地图上的国家涂色,有相邻边界的国家不能用同一种颜色(点相交不算相邻)。(1)试用一种数据结构表示地图上各国相邻的关系;(2)描述涂色过程的算法。 参考答案:

地图涂色问题可以用“四染色“定理。将地图上的国家编号(1到n),从编号1开始逐一涂色,对每个区域用1色,2色,3色,4色(下称“色数”)依次试探,若当前所取颜色与周围已涂色区域不重色,则将该区域颜色进栈;否则,用下一颜色。若1至4色均与相邻某区域重色,则需退栈回溯,修改栈顶区域的颜色。用邻接矩阵数据结构C[n][n]描叙地图上国家间的关系。n个国家用n阶方阵表示,若第i个国家与第j个国家

相邻,则Cij=1,否则Cij=0。用栈s记录染色结果,栈的下标值为区域号,元素值是色数。 void MapColor(AdjMatrix C)

//以邻接矩阵C表示的n个国家的地区涂色 {

int s[]; //栈的下标是国家编号,内容是色数 s[1]=1; //编号01的国家涂1色 i=2;j=1; //i为国家号,j为涂色号 while (i<=n)

{ while (j<=4 && i<=n) {

k=1; //k指已涂色区域号

while (k

//与相邻区不重色,涂色结果进栈,继续对下一区涂色进行试探 }//while (j<=4 && i<=n)

if (j>4) {i--; j=s[i]+1;} //变更栈顶区域的颜色。 }//while(i<=n) }//结束MapColor

20.设有向图G以邻接表形式存储,试基于图的深度优先遍历方法设计一算法,用以判定图中是否存在从顶点vi到顶点vj的路径(i≠j)。 参考答案:

从顶点vi出发进行深度优先遍历,调用完成时所有与vi有路径相通的顶点都被访问到。 Boolean Path(ALGraph G,int i,int j){

//若有向图G中从顶点vi到顶点vj有路径相通,则返回TRUE,否则返回FALSE for(k=0;k

if (visited[j]) return TRUE; else return FALSE; }//Path

void DFS(ALGraph G,int i){//从顶点vi出发对图G进行深度优先遍历 visited[i]=TRUE;

for(p=G.vertices[i].firstarc;p;p=p->next)

//从顶点vi的未被访问的邻接点出发深度优先遍历图G if (!visited[p->adj]) DFS(G,p->adj); }//DFS

21.设有向图G以邻接表形式存储,试基于图的广度优先遍历方法设计一算法,用以判定图中是否存在从顶点vi到顶点vj的路径(i≠j)。 参考答案:

int exist_path_BFS(ALGraph G,int i,int j){ int visited[MAXSIZE]; InitQueue(Q); EnQueue(Q,i);

while(!QueueEmpty(Q)) {

DeQueue(Q,u); visited[u]=1;

for(p=G.vertices[i].firstarc;p;p=p->nextarc) { k=p->adjvex; if(k==j) return 1;

if(!visited[k]) EnQueue(Q,k); }//for }//while return 0;

}//exist_path_BFS

22.试无向图采用邻接表存储结构,试设计算法,判定图中任意给定的两个顶点间是否存在一条长为k的简单路径。 参考答案:

设要判定结点i和结点j间是否存在长为k的简单路径,则只需判定结点i的邻接点l和结点j间是否存在长为k-1的简单路径。 int visited[MAXSIZE];

int exist_path_len(ALGraph G,int i,int j,int k){

if(i==j&&k==0) return 1; //找到了一条路径,且长度符合要求 else if(k>0) { visited[i]=1;

for(p=G.vertices[i].firstarc;p;p=p->nextarc) { l=p->adjvex; if(!visited[l])

if(exist_path_len(G,l,j,k-1)) return 1; //剩余路径长度减一 }//for

visited[i]=0; //本题允许曾经被访问过的结点出现在另一条路径中 }//else

return 0; //没找到 }//exist_path_len

23.已知有向图G中两个顶点u和v,试编写算法求图中从u到v的所有简单路径。 参考答案:

int path[MAXSIZE],visited[MAXSIZE]; //暂存遍历过程中的路径 int Find_All_Path(ALGraph G,int u,int v,int k) {

//初次调用时传入的参数应为G,u,v,0 path[k]=u; //加入当前路径中 visited[u]=1; if(u==v)

{ //找到了一条简单路径 printf(\

for(i=0;path[i];i++) printf(\ //打印输出 } else

for(p=G.vertices[u].firstarc;p;p=p->nextarc)

{

l=p->adjvex;

if(!visited[l]) Find_All_Path(G,l,v,k+1); //继续寻找 }

visited[u]=0;

path[k]=0; //回溯 }//Find_All_Path


第5课 图101106(6).doc 将本文的Word文档下载到电脑 下载失败或者文档不完整,请联系客服人员解决!
× 注册会员免费下载(下载后可以自由复制和排版)

马上注册会员

注:下载文档有可能“只有目录或者内容不全”等情况,请下载之前注意辨别,如果您已付费且无法下载或内容有问题,请联系我们协助你处理。
微信: QQ: