JZOJ5794. 2018.08.10【2018提高组】模拟A组&省选 旅行

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

题解

这题的做法很多,这里就说一种非常简单的做法。
很显然,答案是连续的一段,
就枚举一个下界l,
然后用类似spfa的方法找出这个下界l对于的最大的r,
最后将所有答案去最大值就可以了。

code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string.h>
#include <cmath>
#define N 1003
#define M 103
#define P putchar
#define G getchar
using namespace std;
char ch;
void read(int &n)
{
    n=0;
    ch=G();
    while((ch<'0' || ch>'9') && ch!='-')ch=G();
    int w=1;
    if(ch=='-')w=-1,ch=G();
    while('0'<=ch && ch<='9')n=(n<<3)+(n<<1)+ch-'0',ch=G();
    n*=w;
}

int max(int a,int b){return a>b?a:b;}
int min(int a,int b){return a<b?a:b;}
void write(int x){if(x>9) write(x/10);P(x%10+'0');}

int n,m,x,y,l,r,st,ans,t,mx;
int f[N],q[N*N],head,tail;
int lst[N],to[N*6],nxt[N*6],v1[N*6],v2[N*6],tot;
bool bz[N];

void ins(int x,int y,int l,int r)
{
    nxt[++tot]=lst[x];
    to[tot]=y;
    v1[tot]=l;
    v2[tot]=r;
    lst[x]=tot;
}

void spfa(int p)
{
    memset(f,0,sizeof(f));
    memset(bz,1,sizeof(bz));
    for(head=bz[1]=0,f[q[tail=1]=1]=mx;head<tail;)
    {
        x=q[++head];
        if(f[x]-p<ans)
        {
            bz[x]=1;
            continue;
        }
        for(int i=lst[x];i;i=nxt[i])
            if(v1[i]<=p)
            {
                t=min(f[x],v2[i]);
                if(f[to[i]]<t)
                {
                    f[to[i]]=t;
                    if(bz[to[i]])bz[q[++tail]=to[i]]=0;
                }
            }
        bz[x]=1;
    }
    if(f[n]-p+1>ans)ans=f[n]-p+1,st=p;  
}

int main()
{
    freopen("travel.in","r",stdin);
    freopen("travel.out","w",stdout);

    read(n);read(m);
    for(int i=1;i<=m;i++)
        read(x),read(y),read(l),read(r),ins(x,y,l,r),ins(y,x,l,r),mx=max(mx,r);

    st=ans=0;
    for(int i=1;i<=mx;i++)spfa(i);

    write(ans),P('\n');
    for(int i=0;i<ans;i++)
        write(st+i),P(' ');

    return 0;
}

猜你喜欢

转载自blog.csdn.net/lijf2001/article/details/81570165