B3613 图的存储与出边的排序
看到其他题解用的都是 vector,这里提供一种不一样的思路:用 STL 中的 set 来存图。
解题思路:
我们考虑使用 set<int>s[maxn] 以邻接表的格式存储图。每读取一条边,就用 s[x].insert(y); 存进去。在输出的时候,我们就可以直接输出
set 相比 vector 有一个优势:在插入的时候,它就能够自动去重和排序。也就是说,在插入完毕之后,我们无需像 vector 一样用 sort 扫一遍了。
关于 set 的基本操作:
1.插入
insert(x) 用于将 x 插入到 set 中,并自动递增排序和去重。时间复杂度为
2.获取元素个数。
size() 用来获得 set 中的元素个数,时间复杂度为
3.清空元素
clear() 用来清空 set 中的所有元素,时间复杂度为
4.删除指定元素
erase() 可以删除单个元素,也可以删除一个区间内的所有元素。删除单个元素时可以使用 erase(it),其中 it 为要删除的元素的迭代器,时间复杂度为 erase(x),其中 x 为要删除元素的值,时间复杂度为
s.insert(1);
s.insert(10);
s.insert(100);
s.erase(10);
for(set<int>::iterator it=s.begin();it!=s.end();it++)cout<<*it<<' ';
其输出结果为 1 100。
5.找到对应元素
find(x) 返回的是 set 中对应值为 x 的迭代器,时间复杂度为
s.insert(1);
s.insert(2);
s.insert(3);
printf("%d",*(s.find(2)));
其输出结果为:2
在了解了 set 的基本用法之后,我们来看一看本题的代码:
Code:
#include<cstdio>
#include<set>//set专属头文件
using namespace std;
const int maxn=5e5+5;
int t,n,m,x,y;
set<int>s[maxn];
inline int read(){//快读
int s=0,w=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+ch-48,ch=getchar();
return s*w;
}
inline void write(int x){//快写
if(x<0)putchar('-'),x=-x;
if(x>9)write(x/10);
putchar(x%10+48);
}
int main(){
t=read();
while(t--){
n=read();m=read();
for(int i=1;i<=n;i++)s[i].clear();//在一组数据的开始部分进行初始化,将集合清空。
for(int i=1;i<=m;i++){
x=read();y=read();
s[x].insert(y);//使用邻接表的方式存储图。
}
for(int i=1;i<=n;i++){
for(auto it=s[i].begin();it!=s[i].end();it++)
write(*it),putchar(' ');//遍历输出
putchar('\n');//注意:即使一行中没有输出也要换行
}
}return 0;
}