P1607 [USACO09FEB] temple Fair Shuttle

Keywords: PHP

P1607 [USACO09FEB] temple Fair Shuttle

Title: it's not much for Farmer John to go to the market, exchange prizes and watch the program, but his cows are very lack of exercise - if they want to go to the market all day, they will be exhausted. So in order for the cows to have a good time in the market, John is going to let the cows walk by car. However, John Wood has money. His rented bus can only run along a straight line once in the market, and can only stop at \ (N(1 ≤ n ≤ 20000) \) places (all places are represented by a number between 1 and N). Now the cows are divided into \ (K(1 ≤ K ≤ 50000) \) groups. In group I, there are \ (M_i(1 ≤ M_i ≤ n) \) cows. They want to run from \ (S_i \) to \ (T_i(1 ≤ S_i < t_i ≤ n) \).

Due to the limited capacity of the bus, it may not be able to carry all the cows who want to take the bus. At this time, some cows in the small town are allowed to take the bus separately. John learned through investigation that the capacity of the shuttle bus is \ (C(1 ≤ C ≤ 100)), please help John plan a plan to meet as many cows as possible.

Explanation:

For this problem, it is obviously a greed, and we must consider it as a greed with a mechanism of estoppel. First, at each station, make the following judgment:

  1. The cows that will be in the car can get off
  2. Get all the cows on the train at this station.
  3. If the number is exceeded, drive the farthest destination cow out
#include <iostream>
#include <set>
#include <algorithm>

using namespace std;
typedef long long ll;

const int maxn = 500005;

// A group of cattle
struct group {
    ll s, t, m;
    group() {}
    group(ll s, ll t, ll m) : s(s), t(t), m(m) {}
    // set internal sorting by terminal order
    friend bool operator < (const group &a, const group &b) {
        return a.t < b.t;
    }
} cows[maxn];
ll k, n, c, sum_on_car, ans;

// Group of cattle in the car
multiset<group> cow_set;

// Sort by starting station order
bool cmp(group a, group b) {
    if (a.s == b.s) {
        if (a.t == b.t) {return a.m < b.m;}
        else {return a.t < b.t;}
    } else {return a.s < b.s;}
}

int main() {
    // read
    cin >> k >> n >> c;
    for (int i = 1; i <= k; i ++)
        cin >> cows[i].s >> cows[i].t >> cows[i].m;
    sort(cows + 1, cows + 1 + k, cmp);
    // Start from the first station and traverse to get on the train
    for (int i = 1, j = 0; i <= n; i ++) {
        multiset<group>::iterator begin_iter = cow_set.begin();
        // Get off at the terminal (sequence of terminal)
        while (begin_iter -> t == i) {
            sum_on_car -= begin_iter -> m;
            cow_set.erase(begin_iter);
            begin_iter = cow_set.begin();
        }
        // All aboard
        for (int t = j + 1; t <= k && cows[t].s == i; t ++) {
            j ++;
            cow_set.insert(cows[t]);
            sum_on_car += cows[t].m;
            ans += cows[t].m;
        }
        // The number of people exceeds the standard, and the farthest cattle are deleted.
        while (sum_on_car > c) {
            ll delta = sum_on_car - c;
            multiset<group>::iterator iter = cow_set.end();
            iter --;
            ll all_cow_farthest = iter -> m;
            cow_set.erase(iter);
            if (delta >= all_cow_farthest) {
                sum_on_car -= all_cow_farthest;
                ans -= all_cow_farthest;
            } else {
                ll cow_tmp_s = iter -> s, cow_tmp_t = iter -> t, cow_tmp_m = iter -> m;
                cow_set.insert(group(cow_tmp_s, cow_tmp_t, all_cow_farthest - delta));
                sum_on_car -= delta;
                ans -= delta;
            }
        }
    }
    cout << ans << endl;
    return 0;
}

Posted by doni49 on Mon, 21 Oct 2019 12:15:05 -0700