题意:相当于n个小岛,每个岛上一个人,都要去0岛,给出m张机票的出发日期,出发地,目的地,价格,问是否存在2*n张机票让n个人一起呆在0岛上最少k天,输出最少花费
思路:贪心,我们分别求出去和回来的,在满足n个人都到了的该日期的最少飞机价格,然后我们知道,去的时候,比如我在第8天全都到了,那么第九天买的所有机票,和第八天是一样的,取个最小值,回来的话,相反
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int N=1e6+100; 4 typedef long long ll; 5 const ll INF=1e18; 6 7 struct node{ 8 ll d,f,t,c; 9 }a[N]; 10 ll b[N]; 11 ll dp[1000006],dp1[1000005]; 12 13 bool cmp(node p,node q){ 14 return p.d<q.d; 15 } 16 int main(){ 17 int n,m,k; 18 ll x=1000000,y=-1; 19 cin>>n>>m>>k; 20 for(int i=1;i<=m;i++){ 21 scanf("%lld%lld%lld%lld",&a[i].d,&a[i].f,&a[i].t,&a[i].c); 22 } 23 sort(a+1,a+1+m,cmp); 24 for(int i=1;i<=1000001;i++) b[i]=-1,dp[i]=INF; 25 ll sum=0,s=0; 26 for(int i=1;i<=m;i++){//处理去的机票 27 if(a[i].f==0) continue ; 28 if(b[a[i].f]==-1) { 29 s++;b[a[i].f]=a[i].c;sum+=a[i].c; 30 } 31 else { 32 if(b[a[i].f]>a[i].c){ 33 sum-=b[a[i].f]; 34 sum+=a[i].c; 35 b[a[i].f]=a[i].c; 36 } 37 } 38 if(s==n){ 39 dp[a[i].d]=sum; 40 x=min(x,a[i].d); 41 } 42 } 43 for(int i=1;i<=1000001;i++) b[i]=-1,dp1[i]=INF; 44 sum=0;s=0; 45 for(int i=m;i>=1;i--){//处理回来的机票 46 if(a[i].t==0) continue ; 47 if(b[a[i].t]==-1) { 48 s++;b[a[i].t]=a[i].c;sum+=a[i].c; 49 } 50 else { 51 if(b[a[i].t]>a[i].c){ 52 sum-=b[a[i].t]; 53 sum+=a[i].c; 54 b[a[i].t]=a[i].c; 55 } 56 } 57 if(s==n){ 58 dp1[a[i].d]=sum; 59 y=max(y,a[i].d); 60 } 61 } 62 //cout<<dp1[8]<<" "<<dp1[9]<<" "<<dp1[15]<<endl; 63 for(int i=x+1;i<=1000000;i++) dp[i]=min(dp[i-1],dp[i]); 64 for(int i=y-1;i>=1;i--) dp1[i]=min(dp1[i+1],dp1[i]); 65 66 67 ll ans=INF; 68 for(int i=1;i<=1000000-k-1;i++){ 69 if(dp[i]==INF||dp1[i+k+1]==INF) continue; 70 if(ans>dp[i]+dp1[i+k+1]){ 71 72 ans=dp[i]+dp1[i+k+1]; 73 } 74 75 } 76 if(ans==INF) cout<<-1<<endl; 77 else cout<<ans<<endl; 78 }