Submission #306309


Source Code Expand

#include <bits/stdc++.h>

#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define each(it,n) for(__typeof((n).begin()) it=(n).begin();it!=(n).end();++it)

using namespace std;

typedef long long ll;

struct edge{int to, cap, cost, rev, ocap;};

class MinCostFlow {
public:
    typedef int Int;
    typedef pair<Int, Int> P;
    const Int INF = 1LL << 29;
    
    Int N;
    vector<vector<edge> > G;
    vector<Int> h, dist, prevv, preve;
    
    MinCostFlow(Int N) {
        this->N = N;
        G = vector<vector<edge> >(N);
        h = vector<Int>(N);
        dist = vector<Int>(N);
        prevv = vector<Int>(N);
        preve = vector<Int>(N);
    }
    
    void add_edge(Int from, Int to, Int cap, Int cost) {
        edge e, re;
        e.to = to, e.cap = cap, e.cost = cost, e.rev = G[to].size(), e.ocap = cap;
        G[from].push_back(e);
        re.to = from, re.cap = 0, re.cost = -cost, re.rev = G[from].size() - 1, re.ocap = 0;
        G[to].push_back(re);
    }
    
    Int run(Int s, Int t, Int f) {
        Int res = 0;
        fill(h.begin(), h.end(), 0);
        //fill(prevv.begin(), prevv.end(), 0);
        //fill(preve.begin(), preve.end(), 0);
        while (f > 0) {
            priority_queue<P, vector<P>, greater<P> > que;
            fill(dist.begin(), dist.end(), INF);
            dist[s] = 0;
            que.push(P(0, s));
            while (!que.empty()) {
                P p = que.top(); que.pop();
                Int v = p.second;
                if (dist[v] < p.first) continue;
                for (Int i = 0; i < (Int)G[v].size(); i++) {
                    edge &e = G[v][i];
                    if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
                        dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
                        prevv[e.to] = v;
                        preve[e.to] = i;
                        que.push(P(dist[e.to], e.to));
                    }
                }
            }
            if (dist[t] == INF) {
                return -INF;
            }
            for (Int v = 0; v < N; v++) h[v] += dist[v];
            
            Int d = f;
            for (Int v = t; v != s; v = prevv[v]) {
                d = min(d, G[prevv[v]][preve[v]].cap);
            }
            f -= d;
            res += d * h[t];
            for (Int v = t; v != s; v = prevv[v]) {
                edge &e = G[prevv[v]][preve[v]];
                e.cap -= d;
                G[v][e.rev].cap += d;
            }
        }
        return res;
    }
};

int di[4] = {0, 1, 0, -1}, dj[4] = {1, 0, -1, 0};

int h, w;
int id(int i, int j, bool source) {
    return source ? i * w + j : h * w + i * w + j;
}

int main() {
    cin >> h >> w;
    
    vector<string> field(h);
    rep(i, h) {
        cin >> field[i];
    }

    MinCostFlow flow(h * w * 2 + 1);
    int sink = h * w * 2;

    int si, sj, ai, aj, bi, bj;
    int sid, aid, bid;

    rep(i, h) {
        rep(j, w) {
            if (field[i][j] == '#') continue;
            if (field[i][j] == 'S') {
                si = i, sj = j;
                sid = id(i, j, false);
            }
            if (field[i][j] == 'A') {
                ai = i, aj = j;
                aid = id(i, j, false);
                flow.add_edge(aid, sink, 1, 0);
            }
            if (field[i][j] == 'B') {
                bi = i, bj = j;
                bid = id(i, j, false);
                flow.add_edge(bid, sink, 1, 0);
            }
            flow.add_edge(id(i, j, true), id(i, j, false), 1, 1);

            rep(k, 4) {
                int ti = i + di[k], tj = j + dj[k];
                if (ti < 0 || h <= ti || tj < 0 || w <= tj) continue;
                if (field[ti][tj] == '#') continue;
                flow.add_edge(id(i, j, false), id(ti, tj, true), 1, 0);
            }
        }
    }
    int sa, sb;
    {
        MinCostFlow tmp = flow;
        sa = tmp.run(sid, aid, 1);
    }
    {
        MinCostFlow tmp = flow;
        sb = tmp.run(sid, bid, 1);
    }

    int ans = flow.run(sid, sink, 2);
    cerr << ans << " " << sa << " " << sb << endl;

    if (ans != sa + sb) {
        cout << "NA" << endl;
        return 0;
    }

    rep(k, 2) {
        int id = sid;
        vector<int> pathi, pathj;
        while (id != aid && id != bid) {
            if (id < h * w) {
                pathi.push_back(id / w);
                pathj.push_back(id % w);
            }
            rep(i, flow.G[id].size()) {
                edge &e = flow.G[id][i];
                if (e.cap == 0 && e.cap != e.ocap) {
                    e.cap = e.ocap;
                    id = e.to;
                    break;
                }
            }
        }

        if (id == aid) {
            rep(i, pathi.size() - 1) {
                field[pathi[i]][pathj[i]] = 'a';
            }
        } else {
            rep(i, pathi.size() - 1) {
                field[pathi[i]][pathj[i]] = 'b';
            }
        }
    }

    rep(i, h) {
        cout << field[i] << endl;
    }

    return 0;
}

Submission Info

Submission Time
Task D - Maze
User y3eadgbe
Language C++11 (GCC 4.8.1)
Score 100
Code Size 5205 Byte
Status AC
Exec Time 41 ms
Memory 2868 KB

Judge Result

Set Name all
Score / Max Score 100 / 100
Status
AC × 41
Set Name Test Cases
all manual_j1.txt, manual_j10.txt, manual_j11.txt, manual_j12.txt, manual_j13.txt, manual_j14.txt, manual_j15.txt, manual_j2.txt, manual_j3.txt, manual_j4.txt, manual_j5.txt, manual_j6.txt, manual_j7.txt, manual_j8.txt, manual_j9.txt, manual_k1.txt, manual_k2.txt, random_01.txt, random_02.txt, random_03.txt, random_04.txt, random_05.txt, random_06.txt, random_max_01.txt, random_max_02.txt, random_max_03.txt, random_max_04.txt, random_max_05.txt, random_max_06.txt, random_max_07.txt, random_max_08.txt, random_max_09.txt, random_max_10.txt, sample_01.txt, sample_02.txt, sample_03.txt, sample_04.txt, white_01.txt, white_02.txt, white_03.txt, white_04.txt
Case Name Status Exec Time Memory
manual_j1.txt AC 30 ms 1136 KB
manual_j10.txt AC 27 ms 1176 KB
manual_j11.txt AC 38 ms 2868 KB
manual_j12.txt AC 26 ms 1176 KB
manual_j13.txt AC 29 ms 1108 KB
manual_j14.txt AC 28 ms 1300 KB
manual_j15.txt AC 28 ms 1176 KB
manual_j2.txt AC 33 ms 2016 KB
manual_j3.txt AC 27 ms 1172 KB
manual_j4.txt AC 28 ms 1300 KB
manual_j5.txt AC 27 ms 1168 KB
manual_j6.txt AC 27 ms 1092 KB
manual_j7.txt AC 26 ms 1044 KB
manual_j8.txt AC 26 ms 1044 KB
manual_j9.txt AC 28 ms 1300 KB
manual_k1.txt AC 38 ms 2580 KB
manual_k2.txt AC 41 ms 2576 KB
random_01.txt AC 37 ms 2380 KB
random_02.txt AC 37 ms 2192 KB
random_03.txt AC 33 ms 1940 KB
random_04.txt AC 34 ms 2012 KB
random_05.txt AC 32 ms 1812 KB
random_06.txt AC 31 ms 1812 KB
random_max_01.txt AC 37 ms 2868 KB
random_max_02.txt AC 39 ms 2712 KB
random_max_03.txt AC 36 ms 2580 KB
random_max_04.txt AC 38 ms 2456 KB
random_max_05.txt AC 35 ms 2456 KB
random_max_06.txt AC 36 ms 2368 KB
random_max_07.txt AC 35 ms 2260 KB
random_max_08.txt AC 33 ms 2196 KB
random_max_09.txt AC 35 ms 2088 KB
random_max_10.txt AC 34 ms 2108 KB
sample_01.txt AC 28 ms 1176 KB
sample_02.txt AC 26 ms 1048 KB
sample_03.txt AC 28 ms 1048 KB
sample_04.txt AC 28 ms 1044 KB
white_01.txt AC 37 ms 2864 KB
white_02.txt AC 38 ms 2868 KB
white_03.txt AC 39 ms 2868 KB
white_04.txt AC 37 ms 2864 KB