B3613 图的存储与出边的排序
前置知识
题意
给定一个 个点 条边的有向图 ,结点编号从 至 。对于 ,依次完成如下要求: 对于 的所有出边(即从 出发的边),按照从小到大的顺序输出出边所指向的节点编号。
依次完成的含义是,先按顺序输出 的出边所指向的点的编号,再按顺序输出 的出边所指向的点的编号……最后按顺序输出 的出边所指向的点的编号。
分析
这里给出两种做法:邻接表和链式前向星。
邻接表
- 清空邻接表。
for(int i=1;i<=n;i++)
e[i].clear();
- 存边。
for(int i=1,x,y;i<=m;i++){
x=read();y=read();
e[x].push_back(y);
}
- 对每个点的出边排序,并输出。
for(int i=1;i<=n;i++){
sort(e[i].begin(),e[i].end());
for(int j=0;j<e[i].size();j++)
printf("%d ",e[i][j]);
puts("");
}
链式前向星
- 清空 数组,因为 ,所以
tot=0;
可加可不加。注意不能写成memset(head,0,sizeof(head));
,否则时间复杂度就变成 级别的了。
for(int i=1;i<=n;i++)
head[i]=0;
- 存边
void add(int x,int y){
ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
}
for(int i=1,x,y;i<=m;i++){
x=read();y=read();
add(x,y);
}
- 把每个点的出边放入 类型的 或一个数组 中,注意前面要清空,然后排序并输出(
那还不如直接用邻接表。
for(int i=1;i<=n;i++){
e.clear();
for(int j=head[i];j;j=nxt[j])
e.push_back(ver[j]);
sort(e.begin(),e.end());
for(int j=0;j<e.size();j++)
printf("%d ",e[j]);
puts("");
}
以上两种做法的复杂度都是 。
代码
邻接表
#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long read(){
long long x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int N=5e5+10;
int t,n,m;
vector<int>e[N];
int main(){
t=read();
while(t--){
n=read();m=read();
for(int i=1;i<=n;i++)
e[i].clear();
for(int i=1,x,y;i<=m;i++){
x=read();y=read();
e[x].push_back(y);
}
for(int i=1;i<=n;i++){
sort(e[i].begin(),e[i].end());
for(int j=0;j<e[i].size();j++)
printf("%d ",e[i][j]);
puts("");
}
}
return 0;
}
链式前向星
#include<bits/stdc++.h>
#define ll long long
using namespace std;
long long read(){
long long x=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-') f=-1;ch=getchar();}
while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
return x*f;
}
const int N=5e5+10;
int t,n,m;
int head[N],nxt[N<<1],ver[N<<1],tot;
void add(int x,int y){
ver[++tot]=y,nxt[tot]=head[x],head[x]=tot;
}
vector<int>e;
int main(){
t=read();
while(t--){
n=read();m=read();
for(int i=1;i<=n;i++)
head[i]=0;
for(int i=1,x,y;i<=m;i++){
x=read();y=read();
add(x,y);
}
for(int i=1;i<=n;i++){
e.clear();
for(int j=head[i];j;j=nxt[j])
e.push_back(ver[j]);
sort(e.begin(),e.end());
for(int j=0;j<e.size();j++)
printf("%d ",e[j]);
puts("");
}
}
return 0;
}
本文作者:luckydrawbox
本文链接:https://www.cnblogs.com/luckydrawbox/p/18526564
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
分类:
题解
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步