图论专项菜鸡入门(一):图的储存结构

今天是集训第二部分的开始,展开了图论的学习。上午dalao学长带我们梳理了一下图论的知识点,告诉了我们争取的入门姿势。

现在一边学习一边总结。

一。图的储存结构

 图论图论怎么能没有图呢。所以一开始的关键就是图形的输入。

在大一下的离散数学学习中知道了,想保存图的边等重要的信息,可用邻接矩阵。

这里我将说明邻接矩阵和邻接表

1.临接矩阵

定义:用二维数组,来表示图。这种表示法一般用于稠密图。

无向图中,邻接矩阵是按矩阵副对角线对称的。

我们可以轻松的通过矩阵知道很多信息,包括每个点的度我们都能通过行或列相加得到

但是。。当图不是简单图,邻接矩阵法不能用。

开二维数组,很容易让时间复杂度变大。。毕竟两层for。其实这还好,只不过是TLE。

但是开一个大的二维数组,空间才是最致命的,有的时候数据范围太大了,根本没办法开出来。。

所以,邻接矩阵很多时候只能用在简单的入门范围不大的情况下。

其他题就会显得很力不从心。

2.邻接表

正是因为临界矩阵的不方便,我们引入了邻接表。

a.定义:图的邻接表是图的所有节点的邻接表的集合;而对每个节点,它的邻接表就是它的所有出弧的集合,含有终点,权值等信息。

b.对于有向图G=(V,E),一般用A(v)表示节点v的邻接表,即节点v的所有出弧构成的集合或链表(实际上只需要列出弧的另一个端点,即弧的尾)。

c.一般图都适用。邻接表方法增加或删除一条弧所需的计算工作量很少。

d.有权图的例子:A(1)={2,3},A(2)={4},A(3)={2},A(4)={3,5},A(5)={3,4}

在代码和竞赛中,我们若想对邻接表进行实现,则需要用到C++ STL模板中的vector。

O-先简单说一下vector。

vectorC++标准模板库中的部分内容,它是一个多功能的,能够操作多种数据结构和算法的模板类和函数库。vector之所以被认为是一个容器,是因为它能够像容器一样存放各种类型的对象,简单地说,vector是一个能够存放任意类型的动态数组,能够增加和压缩数据。

Ps:更多用法百度爸爸那里都很全



有向无权图

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#define MAXN 100000+5
using namespace std;
vector<int>Point[MAXN];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int from,to;
    for(int i=0; i<m; i++)
    {
        scanf("%d%d",&from,&to);
        Point[from].push_back(to);
    }
    for(int i=1; i<=n; i++)
    {
        printf("Point%d is related to ",i);
        for(int j=0; j<Point[i].size(); j++)
        {
            printf("%d ",Point[i][j]);
            if(j==Point[i].size()-1)
                printf("\n");
        }
    }

}

无向无权图

#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#define MAXN 100000+5
using namespace std;
vector<int>Point[MAXN];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int from,to;
    for(int i=0; i<m; i++)
    {
        scanf("%d%d",&from,&to);
        Point[from].push_back(to);
        Point[to].push_back(from);
    }
    for(int i=1; i<=n; i++)
    {
        printf("Point%d is related to ",i);
        for(int j=0; j<Point[i].size(); j++)
        {
            printf("%d ",Point[i][j]);
            if(j==Point[i].size()-1)
                printf("\n");
        }
    }

}
有向有权图
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#include<vector>
#define MAXN 100000+5
using namespace std;
struct node
{
    int to,cost;
};
vector<node>Point[MAXN];
int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    int from,to;
    for (int i=0;i<m;i++)
    {
        node c;
       scanf("%d%d%d",&from,&c.to,&c.cost);
        Point[from].push_back(c);
    }
     printf("\n");
    for (int i=1;i<=n;i++)
    {
        for (int j=0;j<Point[i].size();j++)
        {
            printf("Point %d related to %d  cost %d\n",i,Point[i][j].to,Point[i][j].cost);
        }
    }printf("\n");
}


  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值