Jury Meeting CodeForces - 854D

Jury Meeting CodeForces - 854D

思路:暴力枚举会议开始的那一天(只需用所有向0点飞的航班的那一天+1去枚举即可),并计算所有人此情况下去0点和从0点出来的最小花费。

具体:首先,将航班分为飞入0和飞出0两类。 然后,枚举会议开始的时间p。 那么,飞入0的航班只有时间<p的生效,飞出0的航班只有时间>p+k-1的生效。 显然,在p变为p+1时,最多只有各一班航班生效与失效。

(听说还能二分,但是已经打了100行了,不敢再加了。。。好累)

  1 #include<cstdio>
  2 #include<algorithm>
  3 #include<cstring>
  4 using namespace std;
  5 typedef long long LL;
  6 struct Flight
  7 {
  8     LL day,city,cost;
  9     bool operator<(const Flight& b) const
 10     {
 11         return day<b.day||(day==b.day&&city<b.city)||(day==b.day&&city==b.city&&cost<b.cost);
 12     }
 13 }ru[100100],chu[100100];
 14 LL num_ru,num_chu,n,m,k,maxd,ans=0x3f3f3f3f3f3f3f3f;
 15 LL ok_ru,ok_chu;//分别表示现有能进0城市数量与0能到城市数量
 16 LL now_ru,now_chu;//分别表示现有可用的进0航班与不可用的出0航班
 17 LL next_chu[100100];//表示起飞天数在第i架航班之后的与i去同一城市的cost最小的航班编号
 18 LL min_chu[100100],min_index[100100];//表示"现有的"去i城市的cost最小的航班cost及编号
 19 LL now_ru1[100100];//now_chu1[100100];//分别表示现在i到0所用航班与0到i所用航班//now_chu1用min_index代替
 20 LL ans_ru,ans_chu;//分别表示现在入0、出0的cost总量
 21 int main()
 22 {
 23     LL i,t1,t2,t3,t4,j;
 24     scanf("%I64d%I64d%I64d",&n,&m,&k);
 25     for(i=1;i<=m;i++)
 26     {
 27         scanf("%I64d%I64d%I64d%I64d",&t1,&t2,&t3,&t4);
 28         if(t2==0)
 29         {
 30             chu[++num_chu]=(Flight){t1,t3,t4};
 31         }
 32         else
 33         {
 34             ru[++num_ru]=(Flight){t1,t2,t4};
 35             maxd=max(maxd,t1);
 36         }
 37     }
 38     sort(chu+1,chu+num_chu+1);
 39     sort(ru+1,ru+num_ru+1);
 40     memset(min_chu,0x3f,sizeof(min_chu));
 41     for(i=num_chu;i>=1;i--)
 42     {
 43         next_chu[i]=min_index[chu[i].city];
 44         if(min_chu[chu[i].city]>chu[i].cost)
 45         {
 46             min_chu[chu[i].city]=chu[i].cost;
 47             min_index[chu[i].city]=i;
 48         }
 49     }
 50     for(i=1;i<=n;i++)
 51         if(min_index[i]!=0)
 52         {
 53             ok_chu++;
 54             ans_chu+=chu[min_index[i]].cost;
 55         }
 56     if(ok_chu<n)
 57     {
 58         printf("-1");
 59         return 0;
 60     }
 61     now_chu=1;
 62     for(j=1;j<=num_ru;j++)
 63     {
 64         i=ru[j].day+1;
 65         while(ru[now_ru+1].day<i&&now_ru+1<=num_ru)//后来加上&&now_ru+1<=num_ru 
 66         {
 67             now_ru++;
 68             if(now_ru1[ru[now_ru].city]==0)
 69             {
 70                 now_ru1[ru[now_ru].city]=now_ru;
 71                 ans_ru+=ru[now_ru].cost;
 72                 ok_ru++;
 73             }
 74             else if(ru[now_ru1[ru[now_ru].city]].cost>ru[now_ru].cost)
 75             {
 76                 ans_ru-=ru[now_ru1[ru[now_ru].city]].cost;
 77                 now_ru1[ru[now_ru].city]=now_ru;
 78                 ans_ru+=ru[now_ru].cost;
 79             }
 80         }
 81         while(chu[now_chu].day<i+k&&now_chu<=num_chu)//后面加上&&now_chu<=num_chu
 82         {
 83             if(now_chu==min_index[chu[now_chu].city])
 84             {
 85                 ans_chu-=chu[now_chu].cost;
 86                 if(next_chu[now_chu]==0)    goto aaa;
 87                 min_index[chu[now_chu].city]=next_chu[now_chu];
 88                 ans_chu+=chu[next_chu[now_chu]].cost;
 89             }
 90             now_chu++;
 91         }
 92         if(ok_ru==n&&ok_chu==n)
 93             ans=min(ans,ans_ru+ans_chu);
 94     }
 95     aaa:
 96     if(ans==0x3f3f3f3f3f3f3f3f)
 97         printf("-1");
 98     else
 99         printf("%I64d",ans);
100     return 0;
101 }
posted @ 2017-09-08 15:17  hehe_54321  阅读(194)  评论(0编辑  收藏  举报
AmazingCounters.com