• [并查集]JZOJ 5794 旅行


    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从大到小排序,然后我们知道l最后肯定停留在某个li上面,所以我们可以暴力枚举m,然后并查集判断连通性加边即可

    时间复杂度O(m^2)

    #pragma GCC optimize(3)
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    const int N=1001;
    struct Edge {
        int u,v,nx,l,r;
        bool operator < (const Edge &a) const {return r<a.r;}
    }g[3*N];
    int cnt,list[N];
    bool b[N];
    int n,m,ansl,ans;
    int f[N],r[N];
    
    inline void Add(int u,int v,int l,int r) {g[cnt].u=u;g[cnt].v=v;g[cnt].l=l;g[cnt].r=r;g[cnt].nx=list[u];list[u]=cnt++;}
    
    inline int Get_F(int x) {return x==f[x]?x:f[x]=Get_F(f[x]);}
    
    inline int Merge(int x,int y) {
        int i=Get_F(x),j=Get_F(y);
        if (r[i]<r[j]) f[i]=f[j],r[j]=max(r[j],r[i]+1);
        else f[j]=f[i],r[i]=max(r[i],r[j]+1);
    }
    
    void Solve(int lim) {
        for (int i=1;i<=n;i++) f[i]=i,r[i]=1;
        for (int i=m-1;i>=0;i--) {
            if (g[i].l>lim||Get_F(g[i].u)==Get_F(g[i].v)) continue;
            Merge(g[i].u,g[i].v);
            if (Get_F(1)==Get_F(n)) {
                if (g[i].r-lim+1>=ans) {
                    if (g[i].r-lim+1==ans) {
                        ansl=min(ansl,lim);
                    }
                    else ansl=lim;
                    ans=g[i].r-lim+1;
                }
                return;
            }
        }
    }
    
    int main() {
        freopen("travel.in","r",stdin);
        freopen("travel.out","w",stdout);
        scanf("%d%d",&n,&m);
        for (int i=0;i<m;i++) {
            int u,v,l,r;
            scanf("%d%d%d%d",&u,&v,&l,&r);
            Add(u,v,l,r);
        }
        sort(g,g+cnt);
        int maxr;
        for (int i=0;i<m;i++) {
            int l=1,r=m;
            Solve(g[i].l);
        }
        printf("%d\n",ans);
        for (int i=ansl;i<=ans+ansl-1;i++) printf("%d ",i);
        fclose(stdin);fclose(stdout);
    }
    View Code
    在日渐沉没的世界里,我发现了你。
  • 相关阅读:
    ruby基础语法
    几种移动开发技术的比较和选型
    iOS中UIWebView与其中网页的javascript的交互
    android混合开发,webview的java与js互操作
    在学Go语言
    从11对战平台获取玩家数据进行分析
    本地json文件的编辑器,node-webkit开发的exe程序
    51单片机实现多模式计算器
    如何得到个性化banner
    php文件下载服务器代码
  • 原文地址:https://www.cnblogs.com/mastervan/p/9457204.html
Copyright © 2020-2023  润新知