题面:
思路:
看完题目以后,首先有一个结论:每个人都是先去到首都,等待开会,开会结束以后再一个个走掉
而且这道题只有去首都和离开首都的机场
因此考虑计算去首都的飞机的前缀最小花费,以及离开首都的飞机的最小后缀花费
都计算出来以后,对于每一个开始开会的时间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\n",ans); 75 }