• [并差集] Jzoj P5794 旅行


    Description

    悠悠岁月,不知不觉,距那传说中的pppfish晋级泡泡帝已是过 去数十年。数十年 中,这颗泡泡树上,也是再度变得精彩,各种泡泡 天才辈出,惊艳世人,然而,似乎 不论后人如何的出彩,在他们的头 顶之上,依然是有着一道身影而立。 泡泡帝,pppfish。 现在,pppfish即将带着被自己收服的无数个泡泡怪前往下一个 空间,而在前往下 一个空间的道路上,有N个中转站,和M条空间虫洞连接中转站(双向通道,可有重 边,可有环),然而,通过虫洞 是要一定的条件的,pppfish将手下所有泡泡怪编号为 1,2 … +∞,对于每个空间虫洞,有两个值L和R,表示此虫洞只允许编号从L到 R的泡 泡怪通过,pppfish现在在1号中转站,他想带尽可能多的泡 泡怪到达N号中转站,于是 pppfish找到了机智的你,希望你告诉 他最多可以带多少个泡泡怪,同时他还想知道所 有泡泡怪的编号(若 有多组解取字典序最小的一组 )
     

    Input

    第一行两个用空格隔开的整数N,M(2<=N<=1000,0<=M<=3000) 接下来M行,每行四个用空格隔开的整数a,b,l,r 表示在a,b中转站间有一个空间虫洞允许编号l~r的泡泡怪通过。(1<=a, b<=N,1<=l<=r<=1e6

    Output

    第一行一个整数ans,表示最多能携带的泡泡怪数量 接下来一行ans个用空格隔开的正整数,表示泡泡怪的编号,从小到大依次输出,如 果没有泡泡怪能通过只要输出“0”就可以了
     

    Sample Input

    Input1:
    4 4
    1 2 1 10
    2 4 3 5
    1 3 1 5
    2 4 2 7
    Input2:
    2 2
    1 2 1 3
    1 2 4 6 

    Sample Output

    Output1:
    6
    2 3 4 5 6 7 
    Output2:
    3
    1 2 3
     

    Data Constraint

    30%的数据 1 <= N,M <= 10
    100%的数据 2 <= N <= 1000, 0 <= M <= 3000, 1 <= a, b <= N, 1 <= l <= r <= 10^6

    题解

    • 考虑先对所有r端从小到大排序
    • 然后,每次枚举一个r端
    • 然后将所有大于r坐标的路径打入并差集
    • 然后判断1和n是否在同一个并差集里
    • 如果是,则判断r[i]-e[j].l+1是否大于当前ans,更新答案
    • 记录ans的左端点和长度
    • 以便输出泡泡怪的编号

    代码

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <algorithm>
     4 #include <cmath>
     5 #include <cstring>
     6 using namespace std;
     7 struct edge { int a,b,l,r; }e[3010];
     8 int n,m,r[3010],fa[3010],num,mxl;
     9 bool cmp(edge x,edge y) { return x.l<y.l; }
    10 int find(int x) { return fa[x]==x?x:fa[x]=find(fa[x]); }
    11 int main()
    12 {
    13     scanf("%d%d",&n,&m);
    14     for (int i=1;i<=m;i++) scanf("%d%d%d%d",&e[i].a,&e[i].b,&e[i].l,&e[i].r),r[i]=e[i].r;
    15     sort(r+1,r+m+1);
    16     sort(e+1,e+m+1,cmp);
    17     for (int i=1;i<=m;i++)
    18     {
    19         for (int j=1;j<=n;j++) fa[j]=j;
    20         for (int j=1;j<=m;j++)
    21             if (e[j].r>=r[i])
    22             {
    23                 int x=find(e[j].a),y=find(e[j].b);
    24                 if (x!=y) fa[x]=y;
    25                 if (find(1)==find(n)) if (r[i]-e[j].l+1>num) num=r[i]-e[j].l+1,mxl=e[j].l;
    26             }
    27     }
    28     printf("%d
    ",num);
    29     for (int i=mxl;i<=mxl+num-1;i++) printf("%d ",i);
    30     return 0;
    31 }
  • 相关阅读:
    Core Data入门
    web前端开发与iOS终端开发的异同
    Blocks编程
    ARC下循环引用的问题
    小项目
    error: /Users/**/Documents/workspace/***/clean_right_normal.png: No such file or directory
    修复NSTextAlignmentCenter引起的警告
    Implicit conversion loses integer precision: 'long long' to 'NSUInteger' (aka 'unsigned int')
    手势相关函数
    implicit declaration of function setxattr is invalid in c99
  • 原文地址:https://www.cnblogs.com/Comfortable/p/9457026.html
Copyright © 2020-2023  润新知