5821 2023. 10. 02 20:00:35 TuruTamas Barátnők (50 pont) cpp17 Hibás válasz 1/50 164ms 60616 KiB

#include "bits/stdc++.h"
#include <cassert>
#include <climits>
#include <functional>
#include <queue>
#include <vector>
using namespace std;

#define pii pair<int, int>
#define vpii vector<pii>
#define vvpii vector<vpii>
#define pii pair<int, int>
#define vi vector<int>
#define ll long long
const int MOD = ((int)(pow(10, 9) + 7));

struct node {
    vi prev;
    vi next;
    ll d;
    int paths1;
    int paths2;
    bool visited;
};

vvpii graph;
int N;
int M;
int baratno1, baratno2;

vector<node> nodes;

void dijkstra() {
    
    nodes.assign(N, (node) {
        .prev = vi(),
        .next = vi(),
        .d = LLONG_MAX,
        .paths1 = 0,
        .paths2 = 0,
        .visited = false
    });
    
    priority_queue<pii, vpii, greater<>> pq;
    pq.emplace(0, baratno1);
    nodes[baratno1].d = 0;

    while (!pq.empty()) {
        int marked = pq.top().second;
        int d = pq.top().first;
        pq.pop();
        if (d != nodes[marked].d)
            continue;

        for (pii n : graph[marked]) {
            ll old = nodes[n.first].d;
            ll newd = nodes[marked].d + n.second;
            // cout << marked << " to " << n.first << " " << old << " " << newd << endl;
            if (newd < old) {
                nodes[n.first].d = newd;
                pq.emplace(newd, n.first);

                nodes[n.first].prev.clear();
                nodes[n.first].prev.push_back(marked);
            }
            else if (newd == old) {
                nodes[n.first].prev.push_back(marked);
            }
        }
    }
}

void dfs_2_1(int x) {
    node& ez = nodes[x];
    int r = 0;
    nodes[x].visited = true;
    // cout << "in: " << x << "\n";
    for (int next : ez.prev) {
        node& ne = nodes[next];
        ne.next.push_back(x);
        // cout << "looking " << next << ": ";
        if (next == baratno1) {
            // cout << "next == baratno1\n";
            r++;
            r %= MOD;
        }
        else if (!ne.visited) {
            // cout << "!ne.visited\n";
            dfs_2_1(next);
            r += nodes[next].paths1;
            r %= MOD;
        }
        else if (ne.visited) {
            // cout << "ne.visited\n";
            r += nodes[next].paths1;
            r %= MOD;
        }
    }
    ez.paths1 = r;
}

void dfs_1_2(int x) {
    node& ez = nodes[x];
    int r = 0;
    nodes[x].visited = false;
    // cout << "in: " << x << "\n";
    for (int next : ez.next) {
        node& ne = nodes[next];
        // cout << "looking " << next << ": ";
        if (next == baratno2) {
            // cout << "next == baratno2\n";
            r++;
            r %= MOD;
        }
        else if (ne.visited) {
            // cout << "!ne.visited\n";
            dfs_1_2(next);
            r += nodes[next].paths2;
            r %= MOD;
        }
        else if (!ne.visited) {
            r += nodes[next].paths2;
            r %= MOD;
            // cout << "ne.visited\n";
        }
    }
    ez.paths2 = r;

}

int diff = 0;

void dfs_end(int x) {
    // 1_2
    nodes[x].visited = true;
    for (int next : nodes[x].next) {
        if (nodes[next].visited)
            continue;
        int d_here = nodes[x].d;
        int d_next = nodes[next].d;
        int d_end = nodes[baratno2].d;
        // cout << x << " " << next << " " << d_here << " " << d_next << "\n";
        if (d_end % 2 == 0 && d_end / 2 == d_here) {
            // meet here
            diff += (nodes[x].paths1 * nodes[x].paths2) % MOD;
            diff %= MOD;
        }
        else if (d_end / 2 >= d_here && d_end / 2 < d_next) {
            // meet road
            // cout << x << " " << next << "\n";
            diff += (nodes[x].paths1 * nodes[next].paths2) % MOD;
            diff %= MOD;
        }
        else {
            // no meet
            dfs_end(next); 
        }
    }
}

int main() {
    cin >> N >> M;
    graph.assign(N, vector<pii>());
    for (int i = 0; i < M; i++) {
        int a, b, d;
        cin >> a >> b >> d;
        a--; b--;
        graph[a].emplace_back(b, d);
        graph[b].emplace_back(a, d);
    }
    cin >> baratno1 >> baratno2;
    baratno1--; baratno2--;
    dijkstra();
    dfs_2_1(baratno2);
    // cout << "-----------\n";
    dfs_1_2(baratno1);
    // for (int i = 0; i < N; i++) {
    //     auto n = nodes[i];
    //     cout << i << " " /*<< n.d << " "*/ << n.paths1 << " " << n.paths2 << /*" " << n.visited <<*/ "\n" << n.prev.size() << ": ";
    //     for (int i : n.prev)
    //         cout << i << " ";
    //     cout << "\n" << n.next.size() << ": ";
    //     for (int i : n.next)
    //         cout << i << " ";
    //     cout << "\n";
    // }
    dfs_end(baratno1);
    // cout << diff << "\n";
    cout << ((nodes[baratno1].paths2)*(nodes[baratno1].paths2) % MOD - diff) % MOD << endl;
}
Részfeladat Összpont Teszt Verdikt Idő Memória
base 1/50
1 Elfogadva 0/0 3ms 1812 KiB
2 Hibás válasz 0/0 158ms 23884 KiB
3 Hibás válasz 0/2 4ms 4248 KiB
4 Hibás válasz 0/2 4ms 4488 KiB
5 Hibás válasz 0/2 3ms 4572 KiB
6 Hibás válasz 0/2 4ms 4852 KiB
7 Hibás válasz 0/2 4ms 5152 KiB
8 Elfogadva 1/1 72ms 22008 KiB
9 Hibás válasz 0/2 130ms 26656 KiB
10 Hibás válasz 0/2 145ms 29664 KiB
11 Hibás válasz 0/2 141ms 31012 KiB
12 Hibás válasz 0/2 136ms 31480 KiB
13 Hibás válasz 0/2 145ms 33912 KiB
14 Hibás válasz 0/2 143ms 35800 KiB
15 Hibás válasz 0/2 135ms 37640 KiB
16 Hibás válasz 0/1 145ms 35664 KiB
17 Hibás válasz 0/1 157ms 38204 KiB
18 Hibás válasz 0/1 76ms 36604 KiB
19 Hibás válasz 0/2 158ms 42628 KiB
20 Hibás válasz 0/2 155ms 44216 KiB
21 Hibás válasz 0/2 150ms 45000 KiB
22 Hibás válasz 0/2 159ms 46608 KiB
23 Hibás válasz 0/2 164ms 50804 KiB
24 Hibás válasz 0/2 152ms 48800 KiB
25 Hibás válasz 0/2 141ms 45520 KiB
26 Hibás válasz 0/2 153ms 56068 KiB
27 Hibás válasz 0/2 163ms 58012 KiB
28 Hibás válasz 0/2 163ms 60616 KiB
29 Hibás válasz 0/2 150ms 58592 KiB