제출 #1262196

#제출 시각아이디문제언어결과실행 시간메모리
1262196tuanmwillwinvoi26Construction Project 2 (JOI24_ho_t2)C++20
0 / 100
3 ms5444 KiB
#include <bits/stdc++.h>
using namespace std;

#define el '\n'
#define TASK "metro"
#define int long long

const int INF = (int)4e18;
const int MAXN = 200000 + 5;

int n, m;
int s, t, l, k;
vector<pair<int,int>> adj[MAXN];
int dist_s[MAXN], dist_t[MAXN];

void dijkstra(int src, int dist[]) {
    for (int i = 1; i <= n; ++i) dist[i] = INF;
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> pq;
    dist[src] = 0;
    pq.push({0, src});
    while (!pq.empty()) {
        auto cur = pq.top(); pq.pop();
        int d = cur.first, u = cur.second;
        if (d != dist[u]) continue;
        for (auto &e : adj[u]) {
            int v = e.first, w = e.second;
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.push({dist[v], v});
            }
        }
    }
}

// Fenwick for counts
struct Fenwick {
    int n;
    vector<int> ft;
    Fenwick(int _n=0){ init(_n); }
    void init(int _n){ n=_n; ft.assign(n+1,0); }
    void add(int i,int v){ for(; i<=n; i += i&-i) ft[i]+=v; }
    int sum(int i){ int r=0; for(; i>0; i -= i&-i) r+=ft[i]; return r; }
};

signed main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    if (fopen(TASK".inp","r")){
        freopen(TASK".inp","r",stdin);
        freopen(TASK".out","w",stdout);
    }

    cin >> n >> m >> s >> t >> l >> k;
    for (int i = 1; i <= m; ++i) {
        int u, v, w; cin >> u >> v >> w;
        adj[u].push_back({v,w});
        adj[v].push_back({u,w});
    }

    dijkstra(s, dist_s);
    dijkstra(t, dist_t);

    long long W = k - l;

    // vt: chỉ chứa dist_t[j] hữu hạn
    vector<long long> vt;
    vt.reserve(n);
    for (int j = 1; j <= n; ++j) if (dist_t[j] < INF) vt.push_back(dist_t[j]);
    sort(vt.begin(), vt.end());

    // ordered count (including self if it satisfies) but later we'll remove self
    long long res = 0;
    for (int i = 1; i <= n; ++i) {
        if (dist_s[i] == INF) continue;
        long long want = W - dist_s[i];
        if (want < 0) continue;
        long long pos = upper_bound(vt.begin(), vt.end(), want) - vt.begin();
        res += pos;
    }

    // self_count: số i thỏa dist_s[i] + dist_t[i] <= W (và cả hai hữu hạn)
    long long self_count = 0;
    for (int i = 1; i <= n; ++i) {
        if (dist_s[i] < INF && dist_t[i] < INF && dist_s[i] + dist_t[i] <= W) ++self_count;
    }

    // Chuẩn bị cho phần đếm "both" (các cặp {i,j} i!=j mà cả hai hướng đều thỏa)
    // Chỉ lấy các nút có cả hai khoảng cách hữu hạn
    vector<pair<long long,int>> nodesByA;
    vector<long long> allB;
    nodesByA.reserve(n);
    allB.reserve(n);
    for (int j = 1; j <= n; ++j){
        if (dist_s[j] < INF && dist_t[j] < INF){
            nodesByA.push_back({dist_s[j], j});
            allB.push_back(dist_t[j]);
        }
    }
    sort(nodesByA.begin(), nodesByA.end()); // theo A tăng

    // queries: chỉ với i có cả hai khoảng cách hữu hạn
    struct Query { long long alpha; long long beta; };
    vector<Query> queries; queries.reserve(n);
    for (int i = 1; i <= n; ++i){
        if (dist_s[i] < INF && dist_t[i] < INF){
            long long alpha = W - dist_t[i]; // A_j <= alpha
            long long beta  = W - dist_s[i]; // B_j <= beta
            queries.push_back({alpha, beta});
        }
    }
    sort(queries.begin(), queries.end(), [](const Query &a, const Query &b){
        return a.alpha < b.alpha;
    });

    // compress B's (từ allB)
    vector<long long> uniqB = allB;
    sort(uniqB.begin(), uniqB.end());
    uniqB.erase(unique(uniqB.begin(), uniqB.end()), uniqB.end());
    auto getBRank = [&](long long x)->int{
        int pos = upper_bound(uniqB.begin(), uniqB.end(), x) - uniqB.begin(); // pos in [0..sz]
        return pos;
    };

    Fenwick bit((int)uniqB.size() + 5);

    long long ordered_sum_including_self = 0;
    int p = 0; // pointer trên nodesByA
    for (auto &q : queries){
        long long alpha = q.alpha;
        long long beta  = q.beta;
        // thêm tất cả nodes với A_j <= alpha
        while (p < (int)nodesByA.size() && nodesByA[p].first <= alpha){
            int j = nodesByA[p].second;
            long long Bj = dist_t[j];
            int r = getBRank(Bj);
            if (r > 0) bit.add(r, 1);
            p++;
        }
        if (beta < 0) continue;
        int rBeta = getBRank(beta);
        if (rBeta > 0) ordered_sum_including_self += bit.sum(rBeta);
    }

    // ordered_both_excl_self = ordered_sum_including_self - self_count
    long long ordered_both_excl_self = ordered_sum_including_self - self_count;
    if (ordered_both_excl_self < 0) ordered_both_excl_self = 0;
    long long unordered_both = ordered_both_excl_self / 2;

    // Kết luận: ordered res đã gồm các ordered pairs (i,j) (bao gồm self).
    // Để đếm mỗi unordered {i,j} (i!=j) một lần và bỏ hoàn toàn i==j:
    long long answer_no_self = res - unordered_both - self_count;
    if (answer_no_self < 0) answer_no_self = 0;

    cout << answer_no_self << el;
    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

Main.cpp: In function 'int main()':
Main.cpp:50:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   50 |         freopen(TASK".inp","r",stdin);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~
Main.cpp:51:16: warning: ignoring return value of 'FILE* freopen(const char*, const char*, FILE*)' declared with attribute 'warn_unused_result' [-Wunused-result]
   51 |         freopen(TASK".out","w",stdout);
      |         ~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...