제출 #203489

#제출 시각아이디문제언어결과실행 시간메모리
203489triOlympic Bus (JOI20_ho_t4)C++14
100 / 100
377 ms2680 KiB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef long double ld;
typedef pair<int, int> pi;
typedef pair<ll, ll> pl;

typedef vector<int> vi;
typedef vector<ld> vd;
typedef vector<ll> vl;

#define pb push_back
#define f first
#define s second


const int MAXV = 205;
const int MAXE = 5e4 + 10;
const ll INF = 1e15;

int V, E;

int u[MAXE], v[MAXE];
ll c[MAXE], r[MAXE];

int src;
int sink;

int aM[MAXV][MAXV];

ll cost[MAXV];
bool vis[MAXV];

int pEdge[MAXV];

vi sEdges;

void dijkstra() {
    for (int i = 0; i < V; i++) {
        for (int j = 0; j < V; j++) {
            aM[i][j] = -1;
        }
    }

    for (int i = 0; i < E; i++) {
        if (aM[u[i]][v[i]] == -1 || c[aM[u[i]][v[i]]] > c[i]) {
            aM[u[i]][v[i]] = i;
        }
    }

    fill(cost, cost + MAXV, INF);
    fill(vis, vis + MAXV, false);

    fill(pEdge, pEdge + MAXV, -1);
    sEdges.clear();

    cost[src] = 0;

    while (true) {
        int cV = -1;
        for (int i = 0; i < V; i++) {
            if (!vis[i]) {
                if (cV == -1 || cost[i] < cost[cV]) {
                    cV = i;
                }
            }
        }
        if (cV == -1) {
            break;
        }
        vis[cV] = true;

        ll cC = cost[cV];

        for (int aV = 0; aV < V; aV++) {
            int aE = aM[cV][aV];
            if (aE == -1) continue;

            if (cost[aV] > cC + c[aE]) {
                cost[aV] = cC + c[aE];
                pEdge[aV] = aE;
            }
        }
    }

    int cV = sink;
    while (cV != src) {
        if (pEdge[cV] == -1) break;
        sEdges.pb(pEdge[cV]);
        cV = u[pEdge[cV]];

        assert(sEdges.size() < V);
    }
}

bool specEdge[MAXE];

ll g1Cost[MAXV], g2Cost[MAXV];

ll partAns[MAXE];

// compute cost for all reversed edges from src to sink
void computeCost() {
    dijkstra();

//    ps("fin1");

    fill(specEdge, specEdge + MAXE, false);
    for (int x : sEdges) {
        specEdge[x] = true;
    }
    assert(sEdges.size() < V);

    memcpy(g1Cost, cost, sizeof(cost));

    for (int i = 0; i < E; i++) {
        int temp = u[i];
        u[i] = v[i];
        v[i] = temp;
    }
    swap(src, sink);

    dijkstra();
    memcpy(g2Cost, cost, sizeof(cost));
    assert(g1Cost[sink] == g2Cost[src]);

    for (int i = 0; i < E; i++) {
        int temp = u[i];
        u[i] = v[i];
        v[i] = temp;
    }
    swap(src, sink);

//    ps("fin2");

    fill(partAns, partAns + MAXE, INF);

    for (int i = 0; i < E; i++) {
        if (g1Cost[v[i]] < g1Cost[u[i]]) { // edge is against gradient
            partAns[i] = g1Cost[v[i]] + g2Cost[u[i]] + c[i];
            partAns[i] = min(partAns[i], g1Cost[sink]); // don't use reverse edge
        } else {
            if (specEdge[i]) {
                swap(u[i], v[i]);
                dijkstra();
                swap(u[i], v[i]);

                partAns[i] = cost[sink];
            } else {
                partAns[i] = g1Cost[sink]; // just use the already found shortest path
            }
        }
    }
}

ll ans[MAXE];

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> V >> E;

    for (int i = 0; i < E; i++) {
        cin >> u[i] >> v[i] >> c[i] >> r[i];
        u[i]--, v[i]--;
    }

    src = 0;
    sink = V - 1;

    computeCost();
    for (int i = 0; i < E; i++) {
        ans[i] = partAns[i] + r[i];
    }
    ans[E] = g1Cost[sink];

//    ps("half");
//    ps(partAns[1]);

    swap(src, sink);

    computeCost();
    for (int i = 0; i < E; i++) {
        ans[i] += partAns[i];
    }
    ans[E] += g1Cost[sink];
//
//    ps("full");
//    ps(partAns[1]);

    ll fAns = INF;
    for (int i = 0; i <= E; i++) {
        fAns = min(fAns, ans[i]);
    }

    assert(fAns >= 0);

    if (fAns == INF) {
        fAns = -1;
    }
    cout << fAns << endl;
}

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

In file included from /usr/include/c++/7/cassert:44:0,
                 from /usr/include/x86_64-linux-gnu/c++/7/bits/stdc++.h:33,
                 from ho_t4.cpp:1:
ho_t4.cpp: In function 'void dijkstra()':
ho_t4.cpp:94:30: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         assert(sEdges.size() < V);
                ~~~~~~~~~~~~~~^~~
ho_t4.cpp: In function 'void computeCost()':
ho_t4.cpp:114:26: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
     assert(sEdges.size() < V);
            ~~~~~~~~~~~~~~^~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...