图
图的存储
图的遍历
-
深度优先搜先(DFS)
思路:
1)V:出发结点
2)访问V的邻接点V1(V1做已经访问标记)
3)访问V1的邻接点V2(V2做已经访问标记)
4)直到访问到Vn结点 该结点无可访问邻接点
5)从Vn开始原路返回 返回过程中已经访问可访问的结点
重复1)-4)的过程
6)知道原路返回到V结点map[][]//邻接矩阵
visited[]//记录结点是否被访问
注)
连通分支数
即对每个顶点调用dfs(在先前被访问过的顶点不能再被调用)
得到连通分支数
#include<cstdio>
#include<iostream>
using namespace std;
int VNum;
int LNum;
int map[10][10]={0};//邻接矩阵
int visited[10];
void dfs(int vertex)
{
visited[vertex]=1;
cout<<vertex<<" ";
for(int i=0;i<VNum;i++){
if(map[vertex][i]&&!visited[i]) dfs(i);
}
}
int main()
{
cin>>VNum>>LNum;
int v,l;
for(int i=0;i<VNum;i++) visited[i]=0;
for(int i=0;i<LNum;i++){
cin>>v>>l;
map[v][l]=map[l][v]=1;
}
//连通分支
for(int i=0;i<VNum;i++){
if(!visited[i]){
cout<<"{ ";
dfs(i);
cout<<"}"<<endl;
}
}
return 0;
}
#include<iostream>
#include<queue>
using namespace std;
int VNum;
int LNum;
int map[10001][10001];
int visited[10001];
void bfs(int Vertex)
{
cout<<" "<<Vertex;
visited[Vertex]=1;
queue<int> q;
q.push(Vertex);
int tmp;
while(!q.empty()){
tmp=q.front();
q.pop();
for(int i=0;i<VNum;i++){
if(!visited[i]&&map[tmp][i]){
cout<<" "<<i;
q.push(i);
visited[i]=1;
}
}
}
}
int main()
{
int v,l;
cin>>VNum>>LNum;
for(int i=0;i<VNum;i++) visited[i]=0;
for(int i=0;i<LNum;i++){
cin>>v>>l;
map[v][l]=map[l][v]=1;
}
//连通分支
for(int i=0;i<VNum;i++){
if(!visited[i]){
cout<<"{";
bfs(i);
cout<<" }"<<endl;
}
}
return 0;
}
最小生成树(MST)
最短路径
实验
-
建立图的邻接矩阵(或邻接表)存储表示,计算顶点的度(入度、出度),并实现图的深度优先或广度优先遍历。
-
编程实现最小生成树求解的Prim算法。
-
编程实现AOV网的拓扑排序。
-
编程求AOE网的关键路径。
-
编程实现单源点最短路径的Dijkstra算法。
习题
来源于PTA上的习题
PTA-06-图1 列出连通集 //dfs和bfs
06-图2 Saving James Bond - Easy Version //bfs
06-图3 六度空间 //bfs
07-图4 哈利·波特的考试 //Floyd
07-图5 Saving James Bond - Hard Version
PTA-07-图6 旅游规划 //dijkstra
PTA-08-图7 公路村村通 //prim
PTA-08-图8 How Long Does It Take //拓扑排序