제출 #1093437

#제출 시각아이디문제언어결과실행 시간메모리
1093437KindaGoodGamesRobot (JOI21_ho_t4)C++14
0 / 100
1 ms1628 KiB
/*
    Need to consider bidirectional path option.

    Idea was right, just implementation doesn't work :(
*/

#include<bits/stdc++.h>

#define ll long long
#define int ll
#define pii pair<int,int>
#define tiii tuple<int,int,int>
#define tiiii tuple<int,int,int,int>

using namespace std;

ll INF = numeric_limits<ll>::max() / 2;

int result(int n, int m, int s, int t, int ug, int vg, vector<vector<pii>>& adj) {
    // Shortest paths from s to t
    vector<int> dist(n, INF);
    vector<set<int>> pre(n);

    priority_queue<tiii, vector<tiii>, greater<tiii>> pq;
    pq.push({ 0,s,s });
    while (pq.size()) {
        int d, v, p;
        tie(d, v, p) = pq.top();
        pq.pop();
        if (dist[v] < d) continue;
        pre[v].insert(p);
        if (dist[v] == d) continue;
        dist[v] = d;

        for (auto pa : adj[v]) {
            pq.push({ pa.second + d, pa.first, v });
        }
    }

    // run Dijkstra again
    vector<int> dist2(n, INF);
    pq.push({ 0,ug,ug });
    while (pq.size()) {
        int d, v, p;
        tie(d, v, p) = pq.top();
        pq.pop();
        if (dist2[v] <= d) continue;
        dist2[v] = d;

        for (auto pa : adj[v]) {
            pq.push({ pa.second + d, pa.first, v });
        }
    }

    // run Dijkstra again
    vector<int> distVG(n, INF);
    pq.push({ 0,vg,vg });
    while (pq.size()) {
        int d, v, p;
        tie(d, v, p) = pq.top();
        pq.pop();
        if (distVG[v] <= d) continue;
        distVG[v] = d;

        for (auto pa : adj[v]) {
            pq.push({ pa.second + d, pa.first, v });
        }
    }

    // SP Graph
    vector<vector<int>> adjSP(n);
    vector<bool> vis(n);
    queue<int> qp;
    qp.push(t);
    while (qp.size()) {
        int i = qp.front();
        qp.pop();
        if (vis[i]) continue;
        vis[i] = true;
        for (auto u : pre[i]) {
            adjSP[i].push_back(u);
            //adjSP[u].push_back(i);
            if (!vis[u])qp.push(u);
        }
    }
    // remove add help vertices
    queue<tiiii> q; map<pii, int> used;
    int mi = dist2[vg];
    // cur | pre
    q.push({ t,t, INF, INF });
    while (q.size())
    {
        int v, u, d, ds;
        tie(v, u, d, ds) = q.front();
        q.pop();

        //adj[v].push_back({u,0});
        // distance to go from any node in path to the goal
        int newd = min(d, distVG[v]);
        // distance to go to any node in path from start 
        int newds = min(ds, dist2[v]);
        mi = min(mi, newds + newd);
        used[{v, u}]++;

        for (auto w : adjSP[v]) {
            if (used[{w, v}] < 1 && w != v)q.push({ w,v,newd,newds });
            //if(!used.count({v,w}) && w != v)q.push({v,w,newd});
        }
    }


    // do the same thing but other way around
    used.clear();
    q.push({ t,t, INF, INF });
    while (q.size())
    {
        int v, u, d, ds;
        tie(v, u, d, ds) = q.front();
        q.pop();

        //adj[v].push_back({u,0});
        // distance to go from any node in path to the goal
        int newd = min(d, distVG[v]);
        // distance to go to any node in path from start 
        int newds = min(ds, dist2[v]);
        mi = min(mi, newds + newd);
        used[{v, u}]++;

        for (auto w : adjSP[v]) {
            if (used[{w, v}] < 1 && w != v)q.push({ w,v,newd,newds });
            //if(!used.count({v,w}) && w != v)q.push({v,w,newd});
        }
    }

    return min(mi, dist2[vg]);
}
int32_t main() {
    int n, m;
    cin >> n >> m;

    int s, t;
    cin >> s >> t;
    s--; t--;

    int ug, vg;
    cin >> ug >> vg;
    ug--; vg--;

    vector<vector<pii>> adj(n);
    for (int i = 0; i < m; i++) {
        int a, b, c;
        cin >> a >> b >> c;
        a--; b--;
        adj[a].push_back({ b,c });
        adj[b].push_back({ a,c });
    }

    // Subcase 1

    cout << min({ result(n,m,s,t,ug,vg,adj),result(n,m,t,s,vg,ug,adj) }) << endl;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...