图
图
G(V,E) 其中V表示点数,E表示表数
无向图
图的边没有方向,可以双向
有向图
图的边有方向,只能按方向从一点到另一点
完全图
一个n阶的完全无向图含有n*(n-1)/2条边;
一个n阶的完全有向图含有n*(n-1)条边
稠密图
一个边数接近完全图的图
稀疏图
一个边数远远少于完全图的图
节点的度
无向图中与结点相连的边的数目,称为结点的度
结点的入度
在有向图中,以这个结点为终点的有向边的数目
结点的出度
在有向图中,以这个结点为起点的又向边的数目
权值
边的“费用”或"价值" 可以理解为边的长度
连通
如果图中结点U,V之间存在一条从U通过若干条边,点到达V的通路,则称U,V是连通的
回路
起点与终点相同的路径,称为回路或环
强连通分量
有向图中任意两点都连通的最大子图。特殊地,单个点也算一个强连通分量。
图的存储
邻接矩阵(太浪费空间及时间)
采用二维数组实现 如:int g[101][101]
g[i][j]的值,表示从点vi到点vj中的边的权值
ps:int类型最大0x7fffffff(16进制)
存储稠密图时空间以及算力利用率要高一点
CODE:
int g[N][N];
void creae(int g[][]){
int n,e,i,j;
cin>>n>>e;
for(int k=1;k<=e;k++){
cin>>i>>j; //读入边
g[i][j]=1; //赋值,若为无向图还要个给
//g[j][i]赋值
}
}
邻接表(比邻接矩阵更节省时间)
PS:若用stl中的vector还可以节省空间!!!
见代码及注释
code:
//a[i][j]表示和结点i相邻的第j个结点
int a[N][N];
cin>>n>>e;
for(int k=1;k<=e;k++){
cin>>i>>j;
//a[i][0]记录与顶点i邻接的点的个数
a[i][++a[i][0]]=j;
a[j][++a[j][0]]=i;//存无向图时有这句,对称保存
}
图的遍历
深度优先遍历(dfs)
以某个点作为起点,先将该点标记为已访问,然后递归访问所有与之相连且未被访问过的点。
CODE:
#include<iostream>
using namespace std;
const int N=20;
bool v[N];
int n,m,x,y;
bool g[N][N];
void dfs(int st,bool v[]){
cout<<st;
v[st]=1;
for(int i=1;i<=n;i++){
if(!v[i]&&g[st][i]==1) {
cout<<"->";
dfs(i,v);
}
}
}
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
cin>>x>>y;
g[x][y]=1;
g[y][x]=1;
}
dfs(1,v);
return 0;
}