58222023-10-02 21:02:09TuruTamasBarátnők (50 pont)cpp17Wrong answer 4/50188ms31252 KiB

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

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

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

vvpii graph;
ll N;
ll M;
ll 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()) {
        ll marked = pq.top().second;
        ll 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(ll x) {
    node& ez = nodes[x];
    ll r = 0;
    nodes[x].visited = true;
    // cout << "in: " << x << "\n";
    for (ll 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(ll x) {
    node& ez = nodes[x];
    ll r = 0;
    nodes[x].visited = false;
    // cout << "in: " << x << "\n";
    for (ll 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;

}

ll diff = 0;

void dfs_end(ll x) {
    // 1_2
    nodes[x].visited = true;
    for (ll next : nodes[x].next) {
        ll d_here = nodes[x].d;
        ll d_next = nodes[next].d;
        ll 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
            ll paths = nodes[x].paths1 * nodes[x].paths2 % MOD;
            diff += (ll)(pow(paths, 2)) % MOD;
            diff %= MOD;
        }
        else if (d_end / 2 >= d_here && d_end / 2 < d_next) {
            // meet road
            // cout << x << " " << next << "\n";
            ll paths = nodes[x].paths1 * nodes[next].paths2 % MOD;
            diff += (ll)(pow(paths, 2)) % MOD;
            diff %= MOD;
        }
        else if (!nodes[next].visited) {
            // no meet
            dfs_end(next); 
        }
    }
}

int main() {
    cin >> N >> M;
    graph.assign(N, vector<pii>());
    for (ll i = 0; i < M; i++) {
        ll 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 (ll i = 0; i < N; i++) {
    //     auto n = nodes[i];
    //     cout << i << " " /*<< n.d << " "*/ << n.paths1 << " " << n.paths2 << /*" " << n.visited <<*/ "\n" << n.prev.size() << ": ";
    //     for (ll i : n.prev)
    //         cout << i << " ";
    //     cout << "\n" << n.next.size() << ": ";
    //     for (ll i : n.next)
    //         cout << i << " ";
    //     cout << "\n";
    // }
    dfs_end(baratno1);
    // cout << diff << "\n";
    cout << ((nodes[baratno1].paths2)*(nodes[baratno1].paths2) % MOD - diff) % MOD << endl;
}
SubtaskSumTestVerdictTimeMemory
base4/50
1Accepted0/03ms2092 KiB
2Wrong answer0/0181ms27256 KiB
3Wrong answer0/24ms2588 KiB
4Wrong answer0/24ms2792 KiB
5Wrong answer0/23ms2800 KiB
6Wrong answer0/24ms3236 KiB
7Wrong answer0/24ms3468 KiB
8Accepted1/178ms21652 KiB
9Wrong answer0/2136ms27640 KiB
10Wrong answer0/2158ms29752 KiB
11Wrong answer0/2159ms30044 KiB
12Accepted2/2146ms28300 KiB
13Wrong answer0/2162ms29832 KiB
14Wrong answer0/2157ms30604 KiB
15Wrong answer0/2155ms31252 KiB
16Accepted1/1160ms26948 KiB
17Wrong answer0/1170ms27436 KiB
18Wrong answer0/176ms22524 KiB
19Wrong answer0/2179ms29428 KiB
20Wrong answer0/2172ms29244 KiB
21Wrong answer0/2166ms28264 KiB
22Wrong answer0/2171ms28896 KiB
23Wrong answer0/2188ms30748 KiB
24Wrong answer0/2164ms27664 KiB
25Wrong answer0/2146ms22508 KiB
26Wrong answer0/2165ms30604 KiB
27Wrong answer0/2179ms30164 KiB
28Wrong answer0/2185ms31124 KiB
29Wrong answer0/2167ms27184 KiB