PAT---图与图的遍历

图:

PAT (Advanced Level) Practice 用到图的存储方式,但没有用到图的算法的题目

1122 Hamiltonian Cycle (25)

1126 Eulerian Path (25)

1134 Vertex Cover (25)

1142 Maximal Clique (25)

1154 Vertex Coloring (25)

图的遍历:
1.定义:
  • 顶点的度:与该顶点相连的边的条数
  • 顶点和边量化的属性分别为点权和边权
2.存储
邻接矩阵:
  • 对称的矩阵
  • 若题目中不存在权值,G[i][j]=1表示顶点i和顶点j之间有边,G[i][j]=0表示顶点i和顶点j之间不存在边
  • 如果存在权值,G[i][j]存放边权,不存在的边可以设边权为0、-1或是一个很大的数(INF=0x3f3f3f3f)
  • 邻接矩阵只适用于顶点数目不太大(一般不超过1000)的题目
邻接表:
  • 若只存放每条边的终点编号,vector 元素类型定义为 int 即可
vector<int> Adj[N];
Adj[u].push_back(v);
  • 若同时存放终点编号和边权,可建立结构体,vector 元素类型定义为结构体
struct Node{
    int v;
    int weight;
};
vector<Node> Adj[N];
Adj[u].push_back({v,weight});
DFS遍历图:

在这里插入图片描述

DFS的伪代码:
//注意:如果已知给定的图是一个连通图,则只需要一次DFS就能完成遍历

DFS(u) { //访问顶点u
	vis[u]=true;//设置u已被访问
	for(从u出发能到达的所有顶点v)//枚举从u出发可以到达的所有顶点v
		if vis[v]==false //如果v未被访问 
			DFS(v);//递归访问v 
}
DFSTrave(G) { //遍历图G 
	for(G的所有顶点u) //对G的所有顶点u
		if vis[u]==false //如果u未被访问
			DFS(u); //访问u所在的连通块 
	
}

定义:

定义maxn为最大顶点数,INF为无穷大
const int maxn=1000;//最大顶点数
const int INF=0x3f3f3f3f;//无穷大

DFS遍历邻接矩阵:

邻接矩阵
int n,G[maxn][maxn];
bool vis[maxn]= {false};

void DFS(int u,int depth) { //u为当前访问的顶点标号,depth为深度
	vis[u]=true;//设置u已被访问
	//如果需要对u进行一些操作,在这里进行
	//对所有从u出发的分支顶点进行枚举
	for(int v=0; v<n; v++) { //对每个顶点v
		if(vis[v]==false&&G[u][v]!=INF) { //如果v未被访问,且u可到达v
			DFS(v,depth+1);//访问v,深度加1
		}
	}
}

void DFSTrave() { //遍历图G
	for(int u=0; u<n; u++) { //对每个顶点u
		if(vis[u]==false) {//如果u未被访问
			DFS(u,1); //访问u和u所在的连通块,1表示初始为第一层
		}
	}

}

DFS遍历邻接表:

邻接表
vector<int> Adj[maxn];
int n;
bool vis[maxn]={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);
		}
	}
} 
BFS遍历图:

在这里插入图片描述

BFS的伪代码:
BFS(u){
	queue q;
	将u入队;
	inq[u]=true;
	while(!q.empty()){
		取出q的队首元素u进行访问;
		for(从u出发可达的所有顶点v)
			if(inq[v]=false){
				将v入队;
				inq[v]=true; 
			} 
	} 
}
BFSTrave(G){
	for(G的所有顶点u)
		if(inq[u]==false){
			BFS(u);
	}
}

BFS遍历邻接矩阵:

邻接矩阵
int n,G[maxn][maxn];
bool inq[maxn]={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 v=0;v<n;v++){
			if(inq[v]==false&&G[u][v]!=INF){
				q.push(v);
				inq[v]=true;
			}
		}
	}
}
void BFSTrave(){
	for(int u=0;u<n;u++){
		if(inq[u]==false){
			BFS(u);
		}
	}
} 

BFS遍历邻接表:

邻接表
vector<int> Adj[MAXN];
int n;
bool inq[MAXN] = {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]){
                q.push(v);
                inq[v] = true;
            }
        }
    }
}
void BFSTrave(){
    for (int u = 0; u < n; u++)
        if (!inq[u])
            BFS(u);
}
输出结点层号(邻接表):
  • 与树的BFS遍历一样,可能需要输出连通块内所有其他顶点的层号
  • 定义结构体来存放顶点层号
  • 修改邻接表中的元素为Node(int->Node)
  • 当前层号为L,它所有出边的终点的层号都为L+1
struct Node{
    int v;
    int level;
};
vector<Node> Adj[N];
void BFS(int s){
    queue<Node> q;
    Node start = {s,0};
    q.push(start);
    inq[start.v] = true;
    while(!q.empty()){
        Node now = q.front();
        q.pop();
        int u = now.v;
        for (int i = 0; i < Adj[u].size(); i++){
            Node next  = Adj[u][i];
            next.level = now.level + 1;
            if (!inq[next.v]){
                q.push(next);
                inq[next.v] = true;
            }
        }
    }
}
题目链接:

1021 Deepest Root (25)

1076 Forwards on Weibo (30)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值