1 条题解

  • 0
    @ 2025-8-24 21:13:56

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar Firstly
    **

    搬运于2025-08-24 21:13:55,当前版本为作者最后更新于2022-02-06 13:16:20,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    看到其他题解用的都是 vector,这里提供一种不一样的思路:用 STL 中的 set 来存图。

    解题思路:


    我们考虑使用 set<int>s[maxn] 以邻接表的格式存储图。每读取一条边,就用 s[x].insert(y); 存进去。在输出的时候,我们就可以直接输出 sis_i 中存储的所有终点了。

    set 相比 vector 有一个优势:在插入的时候,它就能够自动去重和排序。也就是说,在插入完毕之后,我们无需像 vector 一样用 sort 扫一遍了。

    关于 set 的基本操作:


    1.插入

    insert(x) 用于将 x 插入到 set 中,并自动递增排序和去重。时间复杂度为 O(log2n)O(\log_2 n),其中 n 为 set 中的元素个数。

    2.获取元素个数。

    size() 用来获得 set 中的元素个数,时间复杂度为 O(1)O(1)

    3.清空元素

    clear() 用来清空 set 中的所有元素,时间复杂度为 O(n)O(n)

    4.删除指定元素

    erase() 可以删除单个元素,也可以删除一个区间内的所有元素。删除单个元素时可以使用 erase(it),其中 it 为要删除的元素的迭代器,时间复杂度为 O(1)O(1)。也可以使用 erase(x),其中 x 为要删除元素的值,时间复杂度为 O(log2n)O(\log_2 n)。例如以下一段代码(若 s 为已定义好的 set 集合):

    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 的迭代器,时间复杂度为 O(log2n)O(\log_2 n)。例如以下一段代码:

    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;
    }
    
    • 1

    信息

    ID
    5605
    时间
    1000ms
    内存
    512MiB
    难度
    2
    标签
    递交数
    0
    已通过
    0
    上传者