基本概念
简单来说,点用边连起来就是图。
图是由顶点的有穷非空集合和顶点之间边的集合组成,通常表示为:G = (V,E),其中 V 是非空有限集合, 代表顶点,E 是可以为空的有限集合,代表边。
一些定义和基本概念
- 有向图:图的边有方向,只能按照箭头方向从一点指向零一点
- 无向图:图的边无方向,可以双向
- 节点的度:无向图中与节点相连的边的数目
- 节点的出(入)度:有向图中,以这个点为终(起)点的有向边的数目。
- 权值:边的长度,或者说边的“价值”
- 连通:如果图中节点U、V之间催在一条从U通过若干条边、点到达V点的通路,则称U、V是连通的
- 回路:起点和终点相同的路径,称为回路(或者称为环)
- 完全图:一个n阶的完全无向图含有n×(n-1)/2条边;一个n阶的完全有向图有n×(n-1)条边。 边数接近完全图的图称为稠密图,边数远少于完全图的图成为稀疏图
- 强连通分量:有向图中任意两点都连通的最大子图(形成一个环且方向按照同一个方向)
存储结构
1、二维数组邻接矩阵存储
定义:int G[N][N];//G[i][j]的值表示从点i到点j的边的权值;
当
v
i
v_i
vi和
v
j
v_j
vj之间有边或弧时,G[i][j]=1 或 权值;
当
v
i
v_i
vi和
v
j
v_j
vj之间无边或弧时,G[i][j]=0 或 ∞;
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
const int N = 100 + 10;
//const double PI= acos(-1.0);
//ll ans[N],b[N];
double G[N][N];
int main(){
int n;
double x,y,w;
cin >> n;
//初始化为一个很大的数代表无穷大
memset(G,127,sizeof(G));
for(int i=1;i<=n;i++){
cin >> x >> y >> w;
G[x][y] = G[y][x] = w;
}
return 0;
}
2、数组模拟邻接表
图的邻接表存储法又叫链式存储法,本身是要采用链表实现的,但大多数情况下只要用数组模拟即可。
参考代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 0x7fffffff
const int N = 1e5 + 10;
//const double PI= acos(-1.0);
//ll ans[N],b[N];
struct edge{
int next,to,dis;
}a[N];
int head[1001],num,n,m,u,v,d;
void add(int from,int to,int dis)//加入一条从from到to距离为dis的单向边
{
a[++num].next = head[from];
a[num].to = to;
a[num].dis = dis;
head[from] = num;
}
int main(){
num = 0;
cin >> n >> m;//点数和边数
for(int i=1;i<=m;i++){
cin >> u >> v >> d;
add(u,v,d);
}
for(int i=head[1];i!=0;i=a[i].next){
//边从点1开始的所有边
}
return 0;
}