【CareerCup】Trees and Graphs—Q4.2

转载请注明出处:http://blog.csdn.net/ns_code/article/details/23206519


    题目:

    Given a directed graph, design an algorithm to find out whether there is a route between two nodes.

    翻译:

    给定一个有向图,设计算法判断两结点间是否存在路径。

    思路:

    考察图的遍历,如果遍历路径上经过该顶点,则存在路径,不经过则不存在路径,在遍历算法上做一些改进即可。我们这里用图的DFS来改进。并采用图的BFS和DFS一文中的有向图来作测试,并采用邻接矩阵来存储该有向图中的边和顶点信息。



    实现代码:

/*
DFS遍历保存路过的顶点字符
*/
int count = 0;
char BL[NUM];	//用来保存遍历路过的顶点字符
void DFS(Graph Gp, int begin)
{
	BL[count++] = Gp[begin].data;
	visited[begin] = true; 

	//循环访问当前节点的所有邻接点(即该节点对应的链表)
	int i;
	for(i=first_vertex(Gp,begin); i>=0; i=next_vertex(Gp,begin,i))
	{
		if(!visited[i])  //对于尚未遍历的邻接节点,递归调用DFS
			  DFS(Gp,i);
	}
} 

/*
判断两个顶点是否连通
*/
bool isArrived(Graph Gp,int begin,int end)
{
	DFS(Gp,begin);
	int i;
	for(i=0;i<count;i++)
		if(BL[i] == Gp[end].data)
			return true;
	return false;
}
    完整代码:
/**********************************
题目描述:
给定一个有向图,设计算法判断两结点间是否存在路径
Date:2014-04-08
**********************************/
#define NUM 4          //图中顶点的个数
bool visited[NUM];   //定义全局变量辅助数组,用来保存每个节点的访问信息
/*
用邻接表作为图的存储结构
在邻接表中,用一个一维数组存储图中的每个顶点的信息,
同时为每个顶点建立一个单链表,链表中的节点保存依附在该顶点上的边或弧的信息
*/
typedef struct node
{	//链表中的每个节点,保存依附在该节点上的边或弧的信息
	int vertex;          //在有向图中表示该弧所指向的顶点(即弧头)的位置,
				         //在无向图中表示依附在该边上的另一个顶点的位置
	struct node *pNext;  //指向下一条依附在该顶点上的弧或边
}Node;
typedef struct head
{	//数组中的每个元素,保存图中每个顶点的相关信息
	char data;          //顶点的数据域
	Node *first;        //在有向图中,指向以该顶点为弧尾的第一条弧
						//在无向图中,指向依附在该顶点上的第一条边
}Head,*Graph;           //动态分配数组保存每个顶点的相关信息


//根据图例创建对应的图
Graph create_graph();

//返回图中指定序号顶点的第一个邻接点
int first_vertex(Graph,int);

//返回图中指定序号节点的下一个邻接点
int next_vertex(Graph,int,int);

//DFS保存路过的顶点字符
void DFS(Graph, int);

//判断两顶点是否连通
bool isArrived(Graph,int,int);

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

int main()
{
	Graph Gp = create_graph();

	memset(visited,0,sizeof(visited));
	if(isArrived(Gp,3,2))
		printf("D To C Existed\n");
	else
		printf("D To C Not Existed\n");

	if(isArrived(Gp,1,2))
		printf("B To C Existed\n");
	else
		printf("B To C Not Existed\n");

	if(isArrived(Gp,3,1))
		printf("D To B Existed\n");
	else
		printf("D To B Not Existed\n");

	if(isArrived(Gp,0,3))
		printf("A To D Existed\n");
	else
		printf("A To D Not Existed\n");
	int i;
	//释放掉为每个单链表所分配的内存
	for(i=0;i<NUM;i++)
	{
		free(Gp[i].first);
		Gp[i].first = 0;  //防止悬垂指针的产生
	}

	//释放掉为顶点数组所分配的内存
	free(Gp);
	Gp = 0;
	return 0;
}


/*
根据图例创建对应的图
*/
Graph create_graph()
{
	//为保存顶点相关信息的数组分配空间,并对数据域赋值
	Graph graph = (Graph)malloc(NUM*sizeof(Head));
	int i;
	//顶点的序号按照输入顺序从0依次向后
	for(i=0;i<NUM;i++)
		graph[i].data = 'A' + i;
	
	//为每个节点对应的的单链表中的节点分配空间
	Node *p00 = (Node *)malloc(sizeof(Node));
	Node *p20 = (Node *)malloc(sizeof(Node));
	Node *p21 = (Node *)malloc(sizeof(Node));
	Node *p30 = (Node *)malloc(sizeof(Node));

	//为各单链表中的节点的相关属性赋值
	p00->vertex = 1;
	p00->pNext = NULL;
	p20->vertex = 0;
	p20->pNext = p21;
	p21->vertex = 3;
	p21->pNext = NULL;
	p30->vertex = 0;
	p30->pNext = NULL;

	//将顶点与每个单链表连接起来
	graph[0].first = p00;	
	graph[1].first = NULL;
	graph[2].first = p20;	
	graph[3].first = p30;

	return graph;
}

/*
返回图Gp中pos顶点(序号为pos的顶点)的第一个邻接顶点的序号,如果不存在,则返回-1
*/
int first_vertex(Graph Gp,int pos)
{
	if(Gp[pos].first)  //如果存在邻接顶点,返回第一个邻接顶点的序号
		return 	Gp[pos].first->vertex;
	else              //如果不存在,则返回-1
		return -1;
}

/*
cur顶点是pos顶点(cur和pos均为顶点的序号)的其中一个邻接顶点,
返回图Gp中,pos顶点的(相对于cur顶点)下一个邻接顶点的序号,如果不存在,则返回-1
*/
int next_vertex(Graph Gp,int pos,int cur)
{
	Node *p = Gp[pos].first; //p初始指向顶点的第一个邻接点
	//循环pos节点对应的链表,直到p指向序号为cur的邻接点
	while(p->vertex != cur)
		p = p->pNext;

	//返回下一个节点的序号
	if(p->pNext)
		return p->pNext->vertex; 
	else 
		return -1;
}

/*
DFS遍历保存路过的顶点字符
*/
int count = 0;
char BL[NUM];	//用来保存遍历路过的顶点字符
void DFS(Graph Gp, int begin)
{
	BL[count++] = Gp[begin].data;
	visited[begin] = true; 

	//循环访问当前节点的所有邻接点(即该节点对应的链表)
	int i;
	for(i=first_vertex(Gp,begin); i>=0; i=next_vertex(Gp,begin,i))
	{
		if(!visited[i])  //对于尚未遍历的邻接节点,递归调用DFS
			  DFS(Gp,i);
	}
} 

/*
判断两个顶点是否连通
*/
bool isArrived(Graph Gp,int begin,int end)
{
	DFS(Gp,begin);
	int i;
	for(i=0;i<count;i++)
		if(BL[i] == Gp[end].data)
			return true;
	return false;
}
    测试结果:


    注:代码开源到Github:https://github.com/mmc-maodun/CareerCup


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
贝叶斯网络(Bayesian Networks)和决策图(Decision Graphs)是概率图模型的两种重要表示方法。 贝叶斯网络是一种有向无环图(DAG),用于表示变量之间的概率依赖关系。它由节点和边组成,节点代表变量,边代表变量之间的依赖关系。节点上的条件概率表(CPT)表示了每个变量在给定其父节点的情况下的条件概率分布。贝叶斯网络可以用于推理、预测和决策,能够有效地处理不确定性和复杂的因果关系。通过观察变量的取值,可以通过网络推理得到其他变量的后验概率分布。 决策图是一种扩展了贝叶斯网络的概率图模型,用于表示决策问题中的不确定性。它在贝叶斯网络的基础上增加了决策节点和价值节点。决策节点代表决策者可选择的行动,价值节点代表决策结果的效用或代价。决策图通过考虑不同决策和可能的事件后续产生的不确定性,帮助决策者进行最佳决策的评估。通过采用不同的策略,可以计算出每个决策的期望效用,并选择具有最高期望效用的决策。 贝叶斯网络和决策图是概率模型的重要工具,广泛应用于人工智能、机器学习和决策分析等领域。它们能够帮助我们理解和描述变量之间的关系,优化决策过程,并在不确定性环境中进行推理和预测。同时,对于复杂的问题,可以通过构建和学习这些概率图模型,得到更好的解释和决策支持。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值