图论:图的概念与图的储存方式

转载自http://acm.uestc.edu.cn/bbs/read.php?tid=5670

下载ppt帐号:qscqesze

密码:123456

-------------------------------------------------------------------

1.图的基本概念

图:二元组(V, E) 。V 为顶点集。E为V 中结点之间的边的集合。

自环:一条边的两个端点是相同的。

多重边:两个端点之间有两条以上的边,称他们是多重边。

简单图:没有自环和多重边的图

无向边:边是双向的

有向边:单向边,有箭头

无向图:只有无向边的图

有向图:只有有向边的图

 

顶点的度:
无向图中,一个顶点相连的边数称为该顶点的度。
有向图中,从一个顶点出发的边数称为该顶点得出度;到达该顶点的边数称为它的入度。

权和网:

在图的边给出相关的数,成为权。权可以表示一个顶点到另一个顶点的距离,耗费等。带权图一般成为网。

完全图、稠密图和稀疏图:
任何两个顶点之间都有边(弧)相连称为完全图

边(弧)很少的图称为稀疏图反之为稠密图

2.图的存储

邻接矩阵:

 

int g[max_v+1][max_v+1];
void init()//初始化
{
    for(int i=1;i<=max_v;i++)
        for(int j=1;j<=max_v;j++)
        {
            if(i==j)
                g[i][j]=0;
            else
                g[i][j]=inf;
        }
}
void add_edge(int a,int b,int c)
{
    g[a][b]=g[b][a]=c;//双向边
    //g[a][b]=c;单向边情况
}

 

 

 

空间复杂度:O(V^2)

优点:直观,容易理解,可以直接查看任意两点的关系。
缺点:对于稀疏图,会有很多空间根本没有利用。对于带权图,不能处理重边。要查询某一个顶点的所有边,要枚举V次。

 

在邻接矩阵表示中,除了存放顶点本身信息外,还用一个矩阵表示各个顶点之间的关系。若(i,j)∈E(G)或〈i,j〉∈E(G),则矩阵中第i行 第j列元素值为1,否则为0 。

图的邻接矩阵定义为:
                       1           ,若(i,j)∈E(G)或〈i,j〉∈E(G)
  A[i][j]=
                       0            ,其它情形

例如, 下面为两个无向图和有向图对应的邻接矩阵:

类似地可以定义网的邻接矩阵为:
                   wij           若(i,j)∈E(G)或〈i,j〉∈E(G)
A[i][j]=        0              若i=j
                   ∞            其它情形

图的存储-邻接表

struct Edge
{
    int u,v;//边权
}
vector<Edge> e[max_v+1];
void init()//初始化
{
    for(int i=1;i<=max_v;i++)
        e[i].clear();
}
void add_edge(int a,int b,int c)
{
    e[a].push_back((Edge){b,c});
    e[b].push_back((Edge){a,c});//双向边情况
}


    空间复杂度:有向图O(V+E)无向图O(V+2*E)
    
    优点:节省空间,能快速找到某个顶点所有相连的顶点,而无需访问无关顶点。

对图的每个顶点建立一个单链表(n个顶点建立n个单链表),第i个单链表中的结点包含顶点Vi的所有邻接顶点。

图的储存——前向星

nt first[MAXN];      //first[x]表示顶点x连出去的第一条边的存储位置
int next[MAXM];    //next[i]表示第i条边的下一条边的位置
int v[MAXM];        //v[i]表示第i条边的终点
int w[MAXM];       //w[i]表示第i条边的权值
int  cnt;         //表示当前一共加入多少条边

初始化:memset(first,0,sizeof(first));
             memset(next,0,sizeof(next));
加入一条权值为q的边   x->y : 
cnt++;
next[cnt]=first[x];     first[x]=cnt;  v[cnt]=y;  w[cnt]=q;
使用:for (int i=first[x];i;i=next[i])   {……}    
            //v[i]即为x发出的点,w[i]为相应边的权值

前向星与邻接表相似,不再过多赘述

 

posted @ 2015-05-28 11:58  qscqesze  阅读(1933)  评论(0编辑  收藏  举报