图论预备代码

一、基础

定义边
struct Edge{
	int nextNode; // 下一条结点编号
	int cost; //该边的权重
};

为每一个结点都建立一个单链表来保存与其相邻的边权值和结点的信息。使用vector对象。

vector<Edge> edge[N]
上述单链表的一些操作:
  • 清空单链表
for(int i=0; i<N; i++){
	edge[i].clear(); 
}

向单链表添加信息

Edge tmp; //准备一个Edge结构体
tmp.nextNode = 3; //下一结点编号为3
tmp.cost = 38; //该边权值为38
edge[1].push_back(tmp);//将该边加入结点 1 单链表中
  • 查询某个结点的所有邻接信息(遍历vector)
for(int i=0; i<edge[2].size(); i++){//对edge[2]进行遍历,即对所有与结点2相邻的边进行遍历,edge[2].size()表示其大小
	int nextNode = edge[2][i].nextNode; //读出邻接结点
	int cost = edge[2][i].cost;//读出该边权值
}	
  • 删除结点 1 的单链表中edge[1][i]所对应的边信息
edge[1].erase(edge[1].begin() + i, edge[1].begin() + i + 1);//即vector.erase(vector.begin() + 第一个要删除的元素编号,vector.begin() + 最后一个要删除元素的编号 + 1

二、并查集

定义一个数组,用双亲表示法来表示各种树,(所有集合元素个数总和为N)

int Tree[N];

Tree[i]来表示结点i的双亲结点,若Tree[i]为 -1 则表示该结点不存在双亲结点,即结点 i 为其所在树的根结点。

查找结点 x 所在树的根结点
  • 递归
int findRoot(int x){
	if (Tree[x] == -1) return x; //若当前结点为根结点则返回该结点号
	else return findRoot(Tree [x]); //否则递归查找其双亲结点的根结点
}
  • 非递归
int findRoot(int x){
	int ret;
	while(Tree[x] != -1) x = Tree[x];//若当前结点为非根结点则一直查找其双亲结点
	return ret;
}

若需要在查找过程中添加路径压缩的优化

  • 递归
int findRoot(int x){
	if(Tree[x] == -1) return x;
	else{
		int tmp = findRoot(Tree[x]);
		Tree[x] = tmp;//将当前结点的双亲结点设置为查找返回的根结点编号
		return tmp;
	}
}
  • 非递归
int findRoot(int x) {
	int ret;
	int tmp = x;
	while(Tree[x] != -1) x = Tree[x];
	ret = x;
	x = tmp; //再做一次从结点 x 到根结点的遍历
	while(Tree[x] != -1){
		int t = Tree[x];
		Tree[x] = ret;
		x = t;//遍历过程中将这些结点的双亲结点都设置为已经查找得到的根结点编号
	}
	return ret;
}

结束


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值