流星雨(记忆化搜索)

链接:https://ac.nowcoder.com/acm/contest/547/D
来源:牛客网

题目描述

英仙座流星雨(学名Perseids)是以英仙座γ星附近为辐射点出现的流星雨,也称英仙座γ流星雨。每年在7月20日至8月20日前后出现,于8月13日达到高潮。与象限仪座流星雨、双子座流星雨并称为北半球三大流星雨。

 

暑假到了,又是一个去看流星雨的好季节。

看流星雨最重要的是什么?当然是许愿。

当一颗流星出现时,可以对其许愿。

你一次可以选择一颗流星进行许愿,每一个愿望都需要一定的时间才能说完,而且中间不能有中断。
但是流星的持续时间通常都很短,很难在流星消失之前把自己的一个愿望说完。
你可以朝着新出现的流星接着许上一个未许完的愿望,当且仅当前一颗流星消失的瞬间另外一颗流星同时出现,
你不可以在一颗流星还在出现的时候转向其他的流星,这样流星之神会生气,厄运会降临

现在给你每颗流星出现和结束的时间,问你许一个愿望的最大时长是多少?

输入描述:

第一行一个数n n<=1000000

表示流星的数目

接下来每行2个数字 x,y (0<=x,y<=1001000 )

表示流星出现的时间和结束的时间

输出描述:

一个数字,表示最长可以连续许愿的时间
示例1

输入

复制
3
2 3
2 4
1 2

输出

复制
3

说明

1~4
题意:中文,应该看得懂
思路:将输入的每个流星开始的时间作为起点,进行搜索,找到它所能到达的最远距离(把输入的流星时间段变成一幅单向图),
如果每个都重新搜一遍一定会超时,所以要对搜索过程进行记忆化,将搜索过程的每一结果都用数组存下来,到下次再搜索到时直接取出来用。
代码:
#include<iostream>
#include<cstdio>
#include<queue>
#include<string>
#include<string.h>
#include<map>
#include<vector>
#include<cmath>
#include<iterator>
#define mem(a,b) memset(a,b,sizeof(a)
#define MOD 100000007
#define LL long long
#define Maxn 1000000
const double pi = acos(-1.0);
using namespace std;
int n;
int tol=0;
int head[1001010];
int num[1001010];
//建图 
struct edge{
    int next;
    int to;
}e[Maxn*3];
void add(int start,int ed){
    tol++;
    e[tol].next=head[start];
    e[tol].to=ed;
    head[start]=tol;
}
bool vis[1001010];
int t[Maxn];
//搜索 
int dfs(int start){
    vis[start]=true;
    int tt=-1;
    for(int i=head[start];i;i=e[i].next){
        if(!vis[e[i].to]){//这个点没有被搜索过,进行搜索 
            int uy=dfs(e[i].to);
            //cout<<uy<<"  "<<tt<<endl;
            tt=max(tt,uy);        
        }else{//这个点已经被搜索过了,直接拿出结果来用 
            tt=max(tt,num[e[i].to]);
        }
    }
    if(tt==-1) return start;//这个点已经没有后继点了,返回这个点,这个即是离start最远的点 
    else return num[start]=tt;//这个start有一个可更新的最远终点,进行更新 
}
int main(){
    scanf("%d",&n);
    int start,ed;
    int u=0;
    for(int i=0;i<n;i++){
        scanf("%d%d",&start,&ed);
        add(start,ed);
        t[u++]=start;
    }
    int ans=0;
    for(int i=0;i<u;i++){
        if(!vis[t[i]]){//这个点未被计算过,进行搜索计算最远距离 
            dfs(t[i]);
            ans=max(ans,num[t[i]]-t[i]);//更新答案 
        }
    }
    cout<<ans<<endl;
}

 

posted @ 2019-03-17 14:21  Choose_and_be_chosen  阅读(569)  评论(0编辑  收藏  举报