cf 853 B Jury Meeting [前缀和]

题面:

传送门

思路:

看完题目以后,首先有一个结论:每个人都是先去到首都,等待开会,开会结束以后再一个个走掉

而且这道题只有去首都和离开首都的机场

因此考虑计算去首都的飞机的前缀最小花费,以及离开首都的飞机的最小后缀花费

都计算出来以后,对于每一个开始开会的时间t,用pre[t-1]+suf[t+k]来更新答案即可

Code:

到处都要用long long......

最后我只好ctrl+R,替换int为longlong了......

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #define ll long long
 6 const ll inf=1e15;
 7 using namespace std;
 8 inline ll read(){
 9     ll re=0,flag=1;char ch=getchar();
10     while(ch>'9'||ch<'0'){
11         if(ch=='-') flag=-1;
12         ch=getchar();
13     }
14     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
15     return re*flag;
16 }
17 ll n,m,K,cnta,cntb,cntva,cntvb;
18 ll pre[2000010],suf[2000010];ll suma,sumb;
19 bool vis[100010];ll minn[100010];
20 struct flight{
21     ll to,cost,t;
22 }a[100010],b[100010];
23 bool cmp(flight l,flight r){
24     return l.t<r.t;
25 }
26 bool cmp2(flight l,flight r){
27     return l.t>r.t;
28 }
29 int main(){
30     ll i,j,t1,t2,t3,t4;ll ans=inf;
31     n=read();m=read();K=read();
32     for(i=1;i<=m;i++){
33         t1=read();t2=read();t3=read();t4=read();
34         if(t2!=0) a[++cnta]=(flight){t2,t4,t1};
35         else b[++cntb]=(flight){t3,t4,t1};
36     }
37     if(cnta<n||cntb<n){
38         puts("-1");return 0;
39     }
40     sort(a+1,a+cnta+1,cmp);sort(b+1,b+cntb+1,cmp2);
41     for(i=1;i<=n;i++) suma+=(ll)(minn[i]=inf);
42     t1=1;pre[1]=inf;
43     for(i=1;i<=cnta;i++){
44         for(j=t1+1;j<a[i].t;j++) pre[j]=pre[j-1];
45         t1=a[i].t;
46         if(!vis[a[i].to]) vis[a[i].to]=1,cntva++;
47         suma-=minn[a[i].to]-min(minn[a[i].to],a[i].cost);
48         minn[a[i].to]=min(minn[a[i].to],a[i].cost);
49         if(cntva==n) pre[t1]=suma;
50         else pre[t1]=-1;
51     }
52     memset(vis,0,sizeof(vis));
53     for(i=1;i<=n;i++) sumb+=(ll)(minn[i]=inf);
54     t1=2000005;suf[t1]=inf;
55     for(i=1;i<=cntb;i++){
56         for(j=t1-1;j>b[i].t;j--) suf[j]=suf[j+1];
57         t1=b[i].t;
58         if(!vis[b[i].to]) vis[b[i].to]=1,cntvb++;
59         sumb-=minn[b[i].to]-min(minn[b[i].to],b[i].cost);
60         minn[b[i].to]=min(minn[b[i].to],b[i].cost);
61 //        cout<<"calc "<<i<<ends<<t1<<ends<<cntvb<<ends<<sumb<<endl;
62         if(cntvb==n) suf[t1]=sumb;
63         else suf[t1]=-1;
64     }
65 //    for(i=1;i<=20;i++) cout<<suf[i]<<endl;
66     t1--;while(t1) suf[t1]=suf[t1+1],t1--;
67 //    for(i=1;i<=20;i++) cout<<suf[i]<<endl;
68 //    for(i=1;i<=20;i++) cout<<pre[i]<<endl;
69     for(i=1;i<=cnta;i++){
70         t1=a[i].t;t2=t1+K+1;
71         if(~pre[t1]&&~suf[t2]) ans=min(ans,(ll)pre[t1]+(ll)suf[t2]);
72     }
73     if(ans>=inf) printf("-1");
74     else printf("%I64d
",ans);
75 }
原文地址:https://www.cnblogs.com/dedicatus545/p/8453805.html