作为最简单的存边方式,那当然是要掌握啦。基本原理就是利用f[n][n]来存边。f[i][j]的值若为真,则表明I与j间存在边,否则没有边。既可以存单向边也可以存双向边。同时f也可以存储边的权值。另外根据矩阵乘法的定义,f*f可以表示经过一个中间点后的链接状态。缺点也很明显啦,所占内存过大(尤其是存双向边时),遍历寻找下一个点时效率低等。总体来说数据不是太刁钻时就可以用。
时间o(n ^ 2) , 空间o(n ^ 2)。
#include
using namespace std;
int f[505][505];
int n,m;
void src(int u)//遍历
{
for(int i=1;i<=n;i++)
{
if(f[u][i])
{
src(i);
}
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=0;i<m;i++)//插入,删除再赋值为0就好了
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);//单向边,双向边记得反过来再来一遍
f[x][y]=z;
}
src(1);
return 0;
}
主要用来存稀疏图。基本原理是利用多个单向链表来存边。
时间o(n+m),空间o(n+m)
#include
#include
#include
using namespace std;
int n,m;
int tol;
int hd[50],nxt[500],num[500],w[500];
void add(int u,int v,int w1)
{
if(hd[u])
{
int now=hd[u];
while(nxt[now]) now=nxt[now];
tol++;
nxt[now]=tol;
num[tol]=v;
w[tol]=w1;
return;
}
else
{
tol++;
hd[u]=tol;
tol++;
nxt[hd[u]]=tol;
num[tol]=v;
w[tol]=w1;
}
}
void del(int x,int y)
{
int pr,now=hd[x];
while(num[now]!=y) pr=now,now=nxt[now];
nxt[pr]=nxt[now];
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);//增加由x向y的边
}
int x,y;
scanf("%d%d",&x,&y);
del(x,y);//删除x到y的边
for(int i=1;i<=n;i++)
{
printf("%d\n",i);
int now=nxt[hd[i]];
while(num[now])
{
printf("%d %d\n",num[now],w[now]);
now=nxt[now];
}
}
return 0;
}
这个也比较常用。主要是利用结构体edge来存边,但在使用前需要预处理数据以加快使用。
#include
#include
#include
using namespace std;
int n,m,tol;
int hd[55];
struct edge{
int to;//另一个点
int w;//权
int nxt;//下一个同起点边的下标
}e[5005];
void add(int u,int v,int k)
{
tol++;
e[tol].nxt=hd[u];
e[tol].to=v;
e[tol].w=k;
hd[u]=tol;
}
void del(int u,int v)
{
int pr=0;
for(int i=hd[u];i;i=e[i].nxt)
{
if(e[i].to==v)
{
if(i==hd[u]) hd[u]=e[i].nxt;
else e[pr].nxt=e[i].nxt;
return;
}
pr=i;
}
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y,z;
scanf("%d%d%d",&x,&y,&z);
add(x,y,z);//增加x到y的边
}
int x,y;
scanf("%d%d",&x,&y);
del(x,y);//删除x到y的边;
for(int i=1;i<=n;i++)
{
printf("%d\n",i);
for(int j=hd[i];j;j=e[j].nxt)
{
printf("%d %d\n",e[j].to,e[j].w);
}
}
return 0;
}
简单来说就是邻接矩阵的优化版本。
#include
#include
#include
#include
using namespace std;
vector<int>map[55];
int main()
{
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
{
int x,y;
scanf("%d%d",&x,&y);
map[x].push_back(y);
}
int x,y;
scanf("%d%d",&x,&y);
for(int i=0;i<map[x].size();i++)
{
if(map[x][i]==y)
{
map[x].erase(map[x].begin()+i);
break;
}
}
for(int i=1;i<=n;i++)
{
int len=map[i].size();
printf("%d\n",i);
for(int j=0;j<len;j++)
{
printf("%d ",map[i][j]);
}
cout<<endl;
}
return 0;
}