图的定义、读入与储存

题外话

这篇是我的第一篇博客,希望得到大家的支持。

定义

图(graph)是由两个集合构成,一个是非空但有限的集合V,另一个描述了顶点之间的关系。边的集合为E。

顶点:图中结点称为顶点,第i个顶点记为vi。

边:两个顶点vi和vj相关联称作顶点vi和顶点vj之间有一条边。

有向图和无向图

有向图:有箭头,有方向;

无向图:没有箭头,双向都可。

举两个例子:

比如这张G1,它没有方向,没有箭头,就是无向图。

再比如这张G2,它有方向,有箭头,就是有向图。

对,就是那么简单。

图的读入

这里介绍一种最简单的读入方法。

图主要分两个集合读入:点和边。

先来看点:

点的定义可以有一个变量vertex来表示,就像这样:

const int vertex=10;//点的数量为10

 接下来看边的数量:

首先要知道一个公式:

设点的数量为n,则无向图内:边的数量edge=n(n-1),有向图还需在此基础上/2。

那么我们可以得出:(此处为无向图)

const int edge=vertex*(vertex-1);

接下来,我们还需要两个集合来表示点和边的集合。

点的集合可以用一维数组来储存它们的值。

定义v[i]=j表示第i个节点编号是j,得:

int v[vertex];//点的集合

边的集合

边需要有三个值:左顶点、右顶点、长度。

那么可以简单得知,使用结构体数组struct即可,就像这样: 

struct edges
{
    int from;//该条边的左顶点
    int to;//该条边的右顶点
    double w;//边的长度
};
edges e[edge+1];//边集合数组

存储的变量弄完了,接下来要解决如何输入加边的问题了。

为了美观和方便,我们可以使用一个void函数,其中形式参数为起点、终点和长度。

void add(int u/*起点*/,int v/*终点*/,int w/*长度*/)

函数内部的边的数据切换可以定义一个cnt作为当前在读入的边,初始化赋值为1,之后cnt++进行切换即可。中间再调用结构体数组三个变量进行赋值即可。

void add(int u/*起点*/,int v/*终点*/,int w/*长度*/){
    e[cnt].from=u;//记录第cnt条边的左顶点是u
    e[cnt].to=v;//记录第cnt条边的右顶点是v
    e[cnt].w=w;//记录第cnt条边的长度
    cnt++;//换下一条边去读
}

最后,主函数内再用for循环进行输入和调用函数就能够完成输入了。

for(int i=1;i<=5;i++)//读入
    {
        int u,v,w;//左顶点 右顶点 长度
        cin>>u>>v>>w;
        add(u,v,w);//单向只需这个
        add(v,u,w);//双向
    }

如果想要检查输入是否正确,再加一个for循环进行输出即可。

for(int i=1;i<=5;i++)
    {
        printf("e[%d].from=%d,e[%d].to=%d",i,e[i].from,i,e[i].to);
    }

是不是理解上很简单?

最后,献上完整的读入与输出图的代码:

完整代码

#include<bits/stdc++.h>
using namespace std;
//图的储存
//点集合 边集合
const int vertex=10;//点的数量
const int edge=vertex*(vertex-1);//边的数量 有向就/2
int v[vertex];//点集合 v[i]=j表示第i个节点编号是j
struct edges//边
{
    int from;//该条边的左顶点
    int to;//该条边的右顶点
    double w;//边的长度
};
edges e[edge+1];//边集合
int cnt=1;//当前在读入第cnt条边
void add(int u/*起点*/,int v/*终点*/,int w/*长度*/){
    e[cnt].from=u;//记录第cnt条边的左顶点是u
    e[cnt].to=v;//记录第cnt条边的右顶点是v
    e[cnt].w=w;//记录第cnt条边的长度
    cnt++;//换下一条边去读
}
int main()
{
    for(int i=1;i<=5;i++)//读入
    {
        int u,v,w;// 左顶点 右顶点 长度
        cin>>u>>v>>w;
        add(u,v,w);//单向只需这个
        add(v,u,w);//双向
    }
    for(int i=1;i<=5;i++)
    {
        printf("e[%d].from=%d,e[%d].to=%d",i,e[i].from,i,e[i].to);
    }
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值