Codeforces 853B Jury Meeting
题意
从城市1-n来的评审团到城市0商讨国家大事,离开和抵达的那一天不能讨论,飞机均当天抵达,给出所有飞机起飞抵达代价情况,问能否使所有评审员聚齐连续k天并返回,并求最小代价
思路
从前向后扫一遍,求每天的出发最小代价L[i],从后向前扫,求每天最小离开代价R[i]
从前向后扫一遍,每天的最小代价为L[i]+R[i+k+1]
将每天的默认大小设为1e12,因为最大代价不超过1e11,可以据此确定答案是否合法
代码
#include<bits/stdc++.h> using namespace std; int n,m,k,d,f,t,c; typedef long long ll; const ll inf = 1e12; const int maxn = 1e6+20; ll l[maxn], r[maxn], minn[maxn]; vector< pair<int, int> >to[maxn], back[maxn]; int main(){ scanf("%d %d %d",&n, &m, &k); for(int i = 0;i<m;i++){ scanf("%d %d %d %d",&d, &f,&t, &c); if(t == 0) to[d].push_back({f,c}); else back[d].push_back({t,c}); } ll best = inf*n; for(int i = 1;i<maxn;i++) minn[i] = inf; for(int i = 1;i<maxn;i++){ for(pair<int,int> p : to[i]){ int dest = p.first, cost = p.second; if(cost<minn[dest]) best-= (minn[dest]-cost), minn[dest] = cost; } l[i] = best; } best = inf*n; for(int i = 0;i<maxn;i++) minn[i] = inf; for(int i = maxn-1;i>=1;i--){ for(pair<int,int> p : back[i]){ int dest = p.first, cost = p.second; if(cost<minn[dest]) best-=(minn[dest]-cost), minn[dest] = cost; } r[i] = best; } ll ans = inf*n; for(int i = 1;i<maxn-k-1;i++){ int rr = i+k+1; ans = min(ans,l[i]+r[rr]); } if(ans>=inf) return 0*printf("-1"); return 0*printf("%I64d",ans); }