Codeforces 854 D Jury Meeting(前缀和后缀)

来源:互联网 发布:肩膀痛 知乎 编辑:程序博客网 时间:2024/06/05 18:52

题目地址
题意:从1~n的城市的领导要去0号城市开会,一定要全部到齐了才能开始开会,会议要开k天,给你一个每个航班的飞机票,问最小的花费是多少,如果有领导不能来或者不能走会都不能开,只能输出-1。
思路:我们通过前缀和后缀的思想,把每个时间开会和散会的代价算出来,这就是类似于前缀和的思想,当该天没有算出来,就继承前一天的代价。这样我们就能得到一个表表明了所有天数开会和散会的代价,这样最后枚举一下开会时间就好了。最后判断下有没有值就好了。

#include <iostream>#include <cstring>#include <string>#include <queue>#include <vector>#include <map>#include <set>#include <stack>#include <cmath>#include <cstdio>#include <algorithm>#include <iomanip>#define N 100010#define M 1000010  #define LL __int64#define inf 0x3f3f3f3f3f3f3f3f#define lson l,mid,ans<<1#define rson mid+1,r,ans<<1|1#define getMid (l+r)>>1#define movel ans<<1#define mover ans<<1|1using namespace std;const LL mod = 1000000007;struct node {    int time;    int a, b;    int money;}fly[M];LL sumgo[M], sumback[M];LL flag[M];bool cmp(node a, node b) {    return a.time < b.time;}int main() {    cin.sync_with_stdio(false);    int n, m, k;    LL sum, ans;    int day;    while (cin >> n >> m >> k) {        sum = 0;        day = 0;        memset(sumgo, 0, sizeof(sumgo));        memset(sumback, 0, sizeof(sumback));        for (int i = 0; i < m; i++) {            cin >> fly[i].time >> fly[i].a >> fly[i].b >> fly[i].money;            day = max(day, fly[i].time);        }        sort(fly, fly + m, cmp);        ans = n;        memset(flag, 0, sizeof(flag));        for (int i = 0; i < m; i++) {//算抵达时间            if (fly[i].a) {                if (!flag[fly[i].a]) {                    flag[fly[i].a] = fly[i].money;                    ans--;                    if (!ans) {                        sum = 0;                        for (int i = 1; i <= n; i++) {                            sum += flag[i];                        }                        sumgo[fly[i].time] = sum;                    }                }                else if (flag[fly[i].a] > fly[i].money) {                    if (!ans) {                        sum -= (flag[fly[i].a] - fly[i].money);                        flag[fly[i].a] = fly[i].money;                        sumgo[fly[i].time] = sum;                    }                    else flag[fly[i].a] = fly[i].money;                }            }        }        if (ans) {            cout << -1 << endl;            continue;        }        ans = n;        memset(flag, 0, sizeof(flag));        for (int i = m - 1; i >= 0; i--) {//算抵达时间            if (fly[i].b) {                if (!flag[fly[i].b]) {                    flag[fly[i].b] = fly[i].money;                    ans--;                    if (!ans) {                        sum = 0;                        for (int i = 1; i <= n; i++) {                            sum += flag[i];                        }                        sumback[fly[i].time] = sum;                    }                }                else if (flag[fly[i].b] > fly[i].money) {                    if (!ans) {                        sum -= (flag[fly[i].b] - fly[i].money);                        flag[fly[i].b] = fly[i].money;                        sumback[fly[i].time] = sum;                    }                    else flag[fly[i].b] = fly[i].money;                }            }        }        if (ans) {            cout << -1 << endl;            continue;        }        for (int i = 1; i <= day; i++) {            if (!sumgo[i]) sumgo[i] = sumgo[i - 1];        }        for (int i = day; i > 0; i--) {            if (!sumback[i]) sumback[i] = sumback[i + 1];        }        sum = inf;        for (int i = 1; i < day - k; i++) {            if (sumgo[i] && sumback[i + k + 1]) {                sum = min(sum, sumgo[i] + sumback[i + k + 1]);            }        }        if (sum != inf) {            cout << sum << endl;        }        else {            cout << -1 << endl;        }    }    return 0;}
原创粉丝点击