实现存有向边的几种方法
图论是计算机竞赛的一个重要组成部分,其中存边格式是解决问题的必备基础,那么,今天就在这里给大家介绍几种对有向边的存储方法。
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;
}
注意 : 我们取出的边均为自起始点直接连出的,并无先后关系