建边——邻接矩阵、vector、链式向前星

建边

(图论的中一般都会牵涉到建边的问题,下面的这三种建边的方法视情况选取)

  • 1.1—邻接矩阵
    用邻接矩阵建边的时候,注意题目中可能会有重边!重边!重边!!!(根据情况选短的或长的那条),后面两种方法应该不会受重边的影响(目前还没有遇到过有影响的)
int main()
{
    int sx,ex,len;
    //n个点,m条边
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        memset(mp,INF,sizeof(mp));
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&sx,&ex,&len);//起点、终点、边权
            mp[sx][ex]=len;
            mp[ex][sx]=len;//双向存储
        }
    }
}
  • 1.2—vector存边(邻接表)
    没有权值vector存int ,有全权值的话要用结构体
struct node
{
    int e,len;//边的终点边权
};
vector<node>vt[300];
//vt[i]中存的是以i为起点的边,vt[i][0].e、vt[i][1].e、vt[i][2].e、、、分别表示每条边的终点
int main()
{
    int sx,ex,len;
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        for(int i=0;i<manx;i++)
           vt[i].clear();
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&sx,&ex,&len);
            vt[sx].push_back(node{ex,len});//以sx为起点的边
            vt[ex].push_back(node{sx,len});
        }
    }
}
  • 1.3—链式向前星(邻接表)
    就是用一个结构体数组来表示这个数据结构,通过结构体中记录的相同起点上一条边的编号,访问完所有有相同起点的边
    边建完之后:
    1、edge中存的就是按顺序输入的第1、2、3、、条边的数据
    2、head[i]表示以i为起点的最后一条边的编号(按输入顺序),通过编号找到edge数组中相应边的数据,并逐层向上遍历得到以i为起点的所有边(通过结构体题中的bf遍历)
    3、有的时候有的图可能比较稀疏而且点数较多,邻接矩阵存不下,所以就要用到邻接表。邻接表用vector数组比较方便,但是vector比较慢。所以就有了链式向前星。来自:链式向前星(数组模拟邻接表)
    ps:方法很棒,就是,,,代码有点长
const int manx=1e4+10;
int dis[300],vs[300],head[300];
//dis表示到起点的最短距离
//vs中,1表示已入队,0表示未入队
//head最终存的是以i为终点的最后一条边head[i]
int n,m,cou;
//cou记录每条边的编号
struct node
{
    int e,len,bf;//边的终点、边长、和这个点有相同起点的上一条边的编号
}edge[manx<<2];
void add(int s,int e,int len)
{
     edge[cou]=node{e,len,head[s]};
     head[s]=cou++;//这里可以发现,head[s]中的数据就是以s为起点的“最后一条边”
}
vector<node>vt[300];
int main()
{
    int sx,ex,len;
    while(scanf("%d%d",&n,&m),n||m)
    {
        cou=0;
        memset(head,-1,sizeof(head));//初始化head为-1,表示没有以i为起点的边
        /*也可以初始化为0,但这是cou应初始化为1*/
        for(int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&sx,&ex,&len);
            add(sx,ex,len);
            add(ex,sx,len);
        }
    }
}

遍历相同起点的边

for(int i=head[sx];i!=-1;i=edge[i].bf)//i表示边的编号
    nx=edge[i].e,nlen=edge[i].len;
    //起点:ex,终点:nx,边权:nlen
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值