Участник:ZhenyaStrelkova/GOODA

Материал из DISCOPAL
Перейти к: навигация, поиск

https://www.spoj.com/problems/GOODA/

#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <list>
 
using namespace std;
 
const int max_value = 1100000;
 
int main() {
    int N, M, S, E, C = 0;
    vector<pair<int, int> > cities;
    int used[max_value];
    vector<int> graph[max_value], graph_re[max_value];
    vector<int> order;
    int cost[max_value];
    queue<int> queue_;
 
    long long COST[max_value];
    vector<int> G[max_value];
    long long result[max_value];
 
    cin >> N >> M >> S >> E;
 
    for (int i = 1; i <= N; i++) {
        cin >> cost[i];
    }
 
    for (int i = 1; i <= M; i++) {
        int a, b;
        cin >> a >> b;
        graph[a].push_back(b);
        graph_re[b].push_back(a);
    }
 
    // dfs for traversal order
 
    for (int i = 1; i <= N; i++) {
        if (used[i])
            continue;
        used[i] = 1;
        cities.emplace_back(make_pair(i, 0));
 
        while (!cities.empty()) {
            pair<int, int> P = cities.back();
            cities.pop_back();
            int qv = P.first;
            int qptr = P.second;
            used[qv] = 1;
 
            if (qptr == graph[qv].size()) {
                order.push_back(qv);
                continue;
            }
 
            cities.emplace_back(qv, qptr + 1);
            int to = graph[qv][qptr];
            if (used[to])
                continue;
            cities.emplace_back(to, 0);
        }
    }
 
    reverse(order.begin(), order.end());
 
    for (int i = 1; i <= N; i++)
        used[i] = 0;
 
    for (int id: order) {
        if (used[id])
            continue;
        ++C;
        queue_.push(id);
        while (!queue_.empty()) {
            int v = queue_.front();
            used[v] = C;
            COST[C] += cost[v];
            queue_.pop();
            for (int to: graph_re[v]) {
                if (used[to])
                    continue;
                used[to] = C;
                queue_.push(to);
            }
        }
    }
 
    for (int i = 1; i <= N; i++) {
        for (int j = 0; j < graph[i].size(); j++) {
            int to = graph[i][j];
            if (used[i] == used[to])
                continue;
            G[used[i]].emplace_back(used[to]);
        }
    }
 
    int v1 = used[S];
    int v2 = used[E];
 
    for (int i = 1; i <= C; i++) {
        result[i] = -1e18;
    }
 
    for (int i = C; i; --i) {
        if (i == v2)
            result[i] = COST[i];
        else {
            for (int j = 0; j < G[i].size(); j++) {
                int to = G[i][j];
                result[i] = max(result[i], result[to] + COST[i]);
            }
        }
    }
    cout << result[v1] << endl;
 
    return 0;
}