Codeforces Round #433 Jury Meeting

来源:互联网 发布:北汽黄骅分公司 知乎 编辑:程序博客网 时间:2024/06/05 20:07

D. Jury Meeting

题目链接
题意是给有n个地点,m次航班,每次航班有4个信息,起飞日期di、出发地fi、目的地ti、花费ci,起飞和出发地至少有一个是地点0。现在n个地点,每个地点有一个人,他们要到地点0,当所有人都到达的时候,一起待k天,然后再分别回到n个地点。问说最小的花费是多少,如果达不到这个要求输出-1。

我们考虑从前往后对日期做一个dp,维护dp[i]第i天到达0点的最小花费,再维护一个dis[j],表示从j出发到0的最小花费。每天得到一个航班信息,如果这个出发地还没有过,那么把这个花费算到dp[i]里,更新dis[j],如果这个出发地有过了,但是当前的花费小于dis[j],那么更新一下dp[i]的最小花费,同时更新一下这个dis[j]。注意,当所有人都到达0地的时候我们做一个标记。
然后从后往前同理做一个dp2[i],从后往前地维护第i天离开0地的最小花费,维护方式同上。注意:当所有人离开0地的时候我们也做一个标记
最后答案我们从前往后扫,对于第i天,如果所有人都到达了0地,答案是就是dp[i]加上 ( i + k + 1) 到 最终的航班日期 这段日期中做过标记且花费最少的那部分。(这里我们可以用数组的后缀最值来算比较快,没有标记过的我们算正无穷)。

#include<bits/stdc++.h>using namespace std;#define  LONG long longconst LONG    INF=0x3f3f3f3f;const LONG  MOD=1e9+ 7;const double PI=acos(-1.0);#define clrI(x) memset(x,-1,sizeof(x))#define clr0(x) memset(x,0,sizeof x)#define clr1(x) memset(x,INF,sizeof x)#define clr2(x) memset(x,-INF,sizeof x)#define EPS 1e-10LONG  dp[1001000];LONG  dp1[1001000] ;struct FF{    LONG  d ,f,t,c ;}f[100100];LONG  take[1001000] ;LONG  take1[1001000] ;LONG  dis[100100] ;LONG  Suf[1010000] ;bool cmp(FF a , FF b){    return a.d < b.d ;}int  main(){    LONG  n , m , k ;    set<LONG  > st;    while(cin >> n >> m >>k )    {        clr1(dis) ;clr0(take) ;clr0(take1) ;  clr1(dp) ;clr1(dp1) ;clr1(Suf) ;        st.clear() ;        set<LONG > :: iterator it ;        LONG  l = 19999999999 , r = 0 ;        for(LONG  i = 1;i<= n ; ++ i)st.insert( i ) ;        for(LONG  i =1; i <= m ; ++i)            scanf("%lld%lld%lld%lld",&f[i].d,&f[i].f,&f[i].t,&f[i].c) , l = min(f[i].d , l ) , r = max(f[i].d , r) ;        sort(f + 1 , f + m  + 1 , cmp ) ;        LONG  res =0  ;        for(LONG  i = 1 ; i <= m; ++ i)        {            if(f[i].f == 0 )continue ;            LONG  x = f[i].d ;            if(dis[f[i].f] > f[i].c)            {                dp[x] = res + f[i].c ;                if (dis[f[i].f] < 10000000000000000 ) dp[x] -= dis[f[i].f] ;                else                    st.erase(f[i].f) ;                dis[f[i].f] = f[i].c ;            }            else                dp[x] = res ;            if(st.empty())                take[x] = 1;            res = dp[x] ;        }        for(LONG  i = 1;i<= n ; ++ i)st.insert(i) ;        clr1(dis) ;   res = 0 ;        for(LONG  i = m ; i >= 1 ; -- i)        {            if(f[i].t == 0) continue ;            LONG  x = f[i].d ;            if(dis[f[i].t] > f[i].c )            {                dp1[ x ] = res + f[i].c ;                if(dis[f[i].t] < 1000000000000000 ) dp1[x] -= dis[f[i].t] ;                else                     st.erase(f[i].t) ;                dis[f[i].t] = f[i].c ;            }            else dp1[x] = res ;            if(st.empty())                take1[x] = 1;            res = dp1[x] ;        }        LONG  judge = 0 ;        for(LONG  i = r ;i >= l ; -- i){            if(take1[i])                judge = 1;            if(judge )                Suf[i] = min(Suf[i+1] , dp1[i] ) ;}        LONG  ans =  0x3f3f3f3f3f3f3f3f ;        for(LONG  i = l ; i <= r; ++i)            if(take[i])                ans = min(ans , dp[i] + Suf[i+k+1] ) ;        if(ans == 0x3f3f3f3f3f3f3f3f )            cout<<-1<<endl;        else cout<<ans<<endl;    }}
阅读全文
1 0
原创粉丝点击