图的基本概念
1、基本概念
图:简单的说,图是一个用线或边连接在一起的顶点或节点的集合,严格的说,图是有限顶点V和边E的有序对。
图的表示:一般使用圆圈表示顶点,使用线段表示边,一条边连接两个不同的顶点。有些边是带方向的称为有向边,当顶点v到u含有一条有向边,就画一个箭头从v指向u,使用元组(v,u)表示;而没有方向的边称为无向边,当顶点v到u含有一条有向边,就画一条线段从v指向u,使用元组(v,u)表示。例如下面分别是有向图和无向图。
图根据边的分类分为有向图和无向图,有向图的边是有向边,它就像公路的单行道一样,只能从一个方向到另一个方向。无向图的边是无向边,当然它就像双向车道一样可以互相到达,而且两个顶点是没有区别的。
当且仅当(u,v)是图的边,称顶点v和u是邻接的。边(u,v)关联于顶点u和v。对于无向图这种邻接和关联是对等的,而有向图是单向的,它仅仅从u到v。
权:在图的一些应用中,可能要为每条边赋予一个表示大小的值,这个值就称为权。例如从城市A到城市B存在一条公路,而可以使用权表示这条公路的距离。
路径:一个顶点序列i1,i2…ik是图的一条路径,当且仅当边(i1,i2)(i2,i3)…(ik-1,ik)都在图中。如果除了第一个顶点和最后一个顶点之外,其余的顶点均不相同,那么这条路径称为简单路径。
连通图:设图G是无向图,当且仅当G的每一对顶点之间都有一条路径,则称G是连通图。
子图:如果图H的顶点和边的集合是图G的子集,那么称图H是图G的子图。
生成树:如果图H是图G的子图,且他们的顶点集合相同,并且H是没有环路的无向连通图(即一棵树),则称H是G的一棵生成树。
二分图:图G的顶点被分为两个子集,而且每条边只能从一个子集到另一个子集。例如:
强连通图:图G是一个有向图,当且仅当每一对不同的顶点u,v,从u到v和v到u都有一条有向路径。
自环:边链接的两个点是同一个点
重编:无向图中两点之间有多条边链接,有向图中两点之间同一方向的便超过两条
完全图:简单图,无向图(每个顶点与其余n-1个顶点有边相连),
有向图(每个顶点都有连接到其余n-1个顶点的边)
竞赛图:竞赛图是一定义在有向图上的概念,图中每对不同的顶点通过单个有向边连接,即每对顶点间都有一条有向边。
设 D 为 n 阶有向简单图,若 D 的基图为 n 阶无向完全图,则 D 为 n 阶竞赛图。
2 图的存储
//邻接矩阵
int n,m;
int a[N+5][N+5];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
a[x][y]=a[y][x]=1;
}
}
//邻接表-vector
int n,m;
vector<int> edge[N+5];
int main(){
cin>>n>>m;
for(int i=1;i<=m;i++){
int x,y;
cin>>x>>y;
edge[x].push_back(y);
edge[y].push_back(x);
}
}
//邻接表-指针
int n,m,l=0;
struct Node{
Node *next;
int where;
}*head[N+5],a[2*M+5];
void addedge(int ,int y){
a[++l].where=y;
a[l].next=head[x];
head[x]=&a[l];
}
图的同构
为什么要研究图的同构
●图的结构决定图的本质特征,结构相同的图会有类似的性质,因而需要研究图的同构问题
满足什么条件的图才是图的同构
同构的图案例
任意两个图形,如何判定图的同构
●判断两个图是否同构,目前没有比较好的方法,但是也可以从一些方面着手
○根据节点的度数做初步判定,一度的节点肯定会对应一度的节点,2度节点也肯定对应2度节点
○也可以对节点的邻接节点进行判断,一个节点的邻接点是2度和3度节点,那么在另一个图中也应该是一样的
1在图G1中只有一个一度节点e,G2中也只有一个一度节点v5,所以在图的双射关系中,图G1中的e就应该对应图G2中的v5:e->v5
2同理,在图G1中的6度节点a,也就应该对应图G2中的6度节点v1:a->v1
3·······
4当然如果图的节点和度数规模很大的时候,这种对应关系就会变得很多,所以就不好判断了
图同构的必要条件,也就是说两个图如果同构,会存在的特征
●当图如果不满足下面的条件则这两个图肯定不同构,但是如果满足也不一定同构
图同构的必要条件举例
1在图G和图G’中,图的节点数都相同,且都拥有3个一度节点,2个2度节点,和1个3度节点
2但是可以看到图G中度数为3的节点3,它连接的是1个1度节点(6)和2个2度节点(2和4)
3图G’中度数为3的节点d,它连接的是2个1度节点(f和e)和1个2度节点©
4所以图G和图G’不是同构的图