看到一道题有删边操作,想到了邻接表可不可以删边,没有用邻接表删过边,只有add(),然后就自己写了写删边的函数
图片解释
代码
//邻接表删边
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
int h[N],ne[N],e[N],idx;
int n,m;
void add(int a,int b)
{
e[idx]=b;
//以a为开头的上一条边,若果是第一条则为-1
ne[idx]=h[a];
//以a为开头的边
h[a]=idx++;
}
void solve(int u)
{
//以u为出发点的所有边,现在的h[a]就是最后一个以a为开头的边,然后通过i=ne[i]找到之前的以a为开头的所有边
//直到找到第一条后i=ne[i]=-1结束
for(int i=h[u];~i;i=ne[i])
{
int j=e[i];
printf("%d\n",j);
}
}
//删除a-b这条边
void remove(int a,int b)
{
//遍历以a开头的所有的边
int t=e[h[a]];//删除最后添加的边,只需要改变h[a]遍历起点即可
{
if(t==b)
{
h[a]=ne[h[a]];
}
}
for(int i=h[a];~i;i=ne[i])
{
int j=e[ne[i]];
if(j==b)
{
//现在的idx就是我们要删除的,遍历顺序的前一条边,这时候我们只需要让他指向删除边的后一条边即可
//即使是删除第一条边,也是ne[i]=-1,符合条件
ne[i]=ne[ne[i]];
break;
}
}
}
int main()
{
cin>>n>>m;
memset(h,-1,sizeof(h));
for(int i=0;i<m;i++)
{
int x,y;
cin>>x>>y;
add(x,y);
//输入样例,可以删除1,2 1,3 1,5边界值验证
// 4 4
// 1--2 1--3 1--4 1--5
}
remove(1,2);
//remove(1,5);
//remove(1,5);
solve(1);
return 0;
}