实现存有向边的几种方法

实现存有向边的几种方法


图论是计算机竞赛的一个重要组成部分,其中存边格式是解决问题的必备基础,那么,今天就在这里给大家介绍几种对有向边的存储方法。

vector方法一

利用动态数组vector 我们可以利用pair同时将边的连接节点与权值同时存入,即
vector<pair<节点,边权> >v[50];//空格不能省
vector <pair <int,int> >::iterator it1;
这时,我们只需要进行点->边枚举就可以以链状将所需节点的连通边取出。

vector方法二

与上个方法类似,但这次我们并没有使用一个动态数组,而是两个
vector < int > h[节点],val[边权];
vector <int>::iterator it2;
这两个动态数组的长度是一致的,这也是一个性质

邻接表

邻接表就是利用指针进行存图,每个指针均指向下一个边的存储团,访问完之后,又会由自己的尾指针向下一个存储团指向,这样我们就以线性将图按节点存下了
struct node
{
    int 编号;
    int 权值;
    struct node 指针;
};

struct head_node
{
    struct node 头指针;//头指针可以认为成一个点,没有权值一说。
}pmap[51];

链式前向星

链式前向星可以说是邻接表的一种数组模拟方法,简便易懂,是最常用的一种方法
void l_add(int x,int y,int z)
{
    ++tot;
    val2[tot]=z;
    to[tot]=y;
    after[tot]=head[x];
    head[x]=tot;
}

邻接矩阵

邻接矩阵是最基础的一种存图方法,即利用二维数组来模拟图,但缺点也很明显——无法处理大图

友情提供代码

#include <stdio.h>
#include <vector>
#include <algorithm>
#include <iostream>
using namespace std;
//vector方法一
vector < pair <int,int > > v[50];
vector <pair <int,int> >::iterator it1;
//vector方法二
vector < int > h[50],val[50];
vector <int>::iterator it2;
//链式前向星
int head[50],to[50],tot,after[50],val2[50];

int map[50][50];
//邻接表
struct node
{
    int id;
    int vall;
    struct node *temp;
};
struct head_node
{
    struct node *temp;
}pmap[51];
void j_add(int x,int y,int z)
{
    struct node *where=new node;
    where->id=y;
    where->vall=z;
    where->temp=pmap[x].temp;
    pmap[x].temp=where;
}
//邻接表
void l_add(int x,int y,int z)
{
    ++tot;
    val2[tot]=z;
    to[tot]=y;
    after[tot]=head[x];
    head[x]=tot;
}
int a,b;

int main()
{
    scanf("%d%d",&a,&b);

    for(int x,y,z,i=1;i<=b;i++)
    {
        scanf("%d%d%d",&x,&y,&z);

        v[x].push_back(make_pair(y,z));

        h[x].push_back(y);
        val[x].push_back(z);

        j_add(x,y,z);

        l_add(x,y,z);

        map[x][y]=z;
    }

    puts("");
    puts("vector存边方法一");
    for(int i=1;i<=a;i++)
    {
        printf("%d-> ",i);
        for(it1=v[i].begin();it1!=v[i].end();it1++)     
            printf("%d,%d-> ",it1->first,it1->second);
        printf("NULL\n");
    }

    puts("");
    puts("vector存边方法二");
    for(int i=1;i<=a;i++)
    {
        printf("%d-> ",i);
        for(int j=0;j<h[i].size();j++)
            printf("%d,%d-> ",h[i][j],val[i][j]);
        printf("NULL\n");
    }

    puts("");
    puts("邻接表存边");
    struct node *nex;
    for(int i=1;i<=a;i++)
    {
        printf("%d-> ",i);
        nex=pmap[i].temp;
        while(nex!=NULL)
        {
            printf("%d,%d-> ",nex->id,nex->vall);
            nex=nex->temp;
        }
        printf("NULL\n");
    }

    puts("");
    puts("链式前向星存边");
    for(int i=1;i<=a;i++)
    {
        printf("%d-> ",i);
        for(int j=head[i];j;j=after[j])
            printf("%d,%d-> ",to[j],val2[j]);
        printf("NULL\n");
    }

    puts("");
    puts("邻接矩阵存边");
    for(int i=1;i<=a;i++)
    {
        printf("%d-> ",i);
        for(int j=1;j<=a;j++)
        {
            if(map[i][j]!=0)
                printf("%d,%d-> ",j,map[i][j]);
        }
        printf("NULL\n");
    }
    return 0;
}

注意 : 我们取出的边均为自起始点直接连出的,并无先后关系

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值