图 (Dijkstra)

有向图代码

无向图代代码

邻接矩阵比较简单就直接开一个二维数组就OK

邻接表可以用vector,因为vector是个变长数组嘛,

vector<int> Adj[N];

可以设置出度邻接表,或者入度邻接表

如果需要权值。那就弄个结构体嘛

struct Node{
	int v;	//边的终点编号 
	int w;	//边权 
};
vector<Node> Adj[N];

入队

Node temp;
temp.v = 3;
temp.w = 4;
Adj[1].push_back(temp); 

+构造函数后

struct Node{
	int v;	//边的终点编号 
	int w;	//边权 
	Node(int _v, int _w) : v(_v), w(_w){}
};
Adj[1].push_back(Node(3, 4));

连通分量无向图中,两个顶点之间可以互相到达,那么就称这两个顶点连通,如果图G(V, E)的任意两个顶点都强连通,则称图G为强连通图,否则称G为非连通图,且称其中的极大连通子图为连通分量。

强连通分量:有向图中,如果两个顶点可以各自通过一条有向路径到达另一个顶点,就称这两个顶点强联通,如果图G(V,E)的任意两个顶点都是强连通,则图G为强联通图(还有单向连通,弱连通)强连通(一条回路)单向连通(一条通路)弱连通(不是上面两种情况),如果G非强连通,称其中的极大强连通子图为强连通分量。

建议画图

1)邻接矩阵版本DFS

int n, G[MAXV][MAXV];
bool vis[MAXV] = {false};
void DFS(int u, int depth){	//这款可以记录深度 
	vis[u] = true;
	for(int v = 0; v < n; v++){
		if(vis[v] == false && G[u][v] != INF){
			DFS(v, depth + 1);
		}
	}
} 
void DFSTrave(){
	for(int u = 0; u < n; u++){
		if(vis[u] == false){
			DFS(u, 1);
		}
	}
} 

2)邻接表版DFS (vector)

vector<int> Adj[MAXV];
int n;
bool vis[MAXV] = {false};
void DFS(int u, int depth){
	vis[u] = true;
	for(int i = 0; i < Adj[u].size(); i++){
		int v = Adj[u][i];
		if(vis[v] == false){
			DFS(v, depth + 1);
		}
	}
}
void DFSTrave(){
	for(int u = 0; u < n; u++){
		if(vis[u] == false){
			DFS(u, 1);
		}
	}
} 

伪代码

DFS(u){
	vis[u] = true;
	for(从u出发能到达的所有顶点v){
		if(vis[v] == false){
			DFS(v);
		} 
	}
}
DFSTrave( G ){
	for(G的所有顶点u){
		if(vis[u] == false){
			DFS(u);		//访问 u所在的连通区域 
		} 
	} 
}

1)邻接矩阵 BFS

int n, G[MAXV][MAXV];
bool inq[MAXV] = {false};

void BFS(int u){
	queue<int> q;
	q.push(u);
	inq[u] = true; 	//inq[]数组是判断是否已经入过队,而不是访问过没有。
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int v = 0; v < n; v++){
			if(inq[v] == false && G[u][v] != INF){
				q.push(v);
				inq[v] = true;
			}
		}
	}	 
} 

2)邻接表BFS

int n, G[MAXV][MAXV];
bool inq[MAXV] = {false};

void BFS(int u){
	queue<int> q;
	q.push(u);
	inq[u] = true;
	while(!q.empty()){
		int u = q.front();
		q.pop();
		for(int i = 0; i < Adj[u].size(); i++){
			int v = Adj[u][i];
			if(inq[v] == false){
				q.push(v);
				inq[v] = true;
			}
		}
	}
}

遍历图

void BFSTrave(){
	for(int u = 0; u < n; u++){
		if(inq[u] == false){
			BFS(u);
		}
	}
}

伪代码

BFS(u){
	queue q;
	inq[u] = true;
	while(q非空){
		取出队首元素u进行访问
		for(从u出发可达到的所有顶点v){
			if(inq[v] == false){
				将v入队;
				inq[v] = true; 
			}
		} 
	} 
}

稍微拓展,比如有时记录层数,或者记录步数。

我们需要用到结构体

struct Node {
	int v;	//顶点编号 
	int layer;	//顶点层号 
};

我们用邻接表的BFS实现下,矩阵一样的。

vector<Node> Adj[N];

解释下,如果当前层号为L,那么它所有出边的终点的层号都为L + 1,

void BFS(int s){
	queue<Node> q;
	Node start;
	start.v = s;
	start.layer = 0;
	q.push(start);
	inq[start.v] = true;
	while(!q.empty()){
		Node topNode = q.front();
		q.pop();
		int u = topNode.v;
		for(int i = 0; i < Adj[u].size(); i++){
			Node next = Adj[u][i];
			next.layer = topNode.layer + 1;
			if(inq[next.v] == false){
				q.push(next);
				inq[next.v] = true;
			}
		}
	}
} 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值