BZOJ 1001. [BeiJing2006]狼抓兔子

 

做法一:直接dinic跑

做法二:平面图最小割转对偶图最短路,左下外区域为起点,右上外区域为终点,一条边连接两个区域,把区域看成点,就变成了最短路问题。

#include <bits/stdc++.h>

namespace IO {
char buf[1 << 21], buf2[1 << 21], a[20], *p1 = buf, *p2 = buf, hh = '\n';
int p, p3 = -1;
void read() {}
void print() {}
inline int getc() {
    return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++;
}
inline void flush() {
    fwrite(buf2, 1, p3 + 1, stdout), p3 = -1;
}
template <typename T, typename... T2>
inline void read(T &x, T2 &... oth) {
    T f = 1; x = 0;
    char ch = getc();
    while (!isdigit(ch)) { if (ch == '-') f = -1; ch = getc(); }
    while (isdigit(ch)) { x = x * 10 + ch - 48; ch = getc(); }
    x *= f;
    read(oth...);
}
template <typename T, typename... T2>
inline void print(T x, T2... oth) {
    if (p3 > 1 << 20) flush();
    if (x < 0) buf2[++p3] = 45, x = -x;
    do {
        a[++p] = x % 10 + 48;
    } while (x /= 10);
    do {
        buf2[++p3] = a[p];
    } while (--p);
    buf2[++p3] = hh;
    print(oth...);
}
}

const int N = 2e6 + 7, M = 6e6 + 7;
const int INF = 0x3f3f3f3f;
struct E {
    int v, ne, c;
} e[M];
int head[N], cnt = 1, n, m, id[1007][1007][2], tol;
int dis[N];

inline void add(int u, int v, int c) {
    e[++cnt].v = v; e[cnt].ne = head[u]; e[cnt].c = c; head[u] = cnt;
    std::swap(u, v);
    e[++cnt].v = v; e[cnt].ne = head[u]; e[cnt].c = c; head[u] = cnt;
}

#define pii pair<int, int>
#define fi first
#define se second
bool done[N];

int dijkstra(int s, int t) {
    for (int i = 1; i <= tol; i++)
        dis[i] = INF;
    dis[s] = 0;
    std::priority_queue< std::pii, std::vector<std::pii>, std::greater<std::pii> > que;
    que.push(std::pii(0, s));
    while (!que.empty()) {
        std::pii p = que.top(); que.pop();
        int u = p.se;
        if (u == t) break;
        if (done[u]) continue;
        done[u] = 1;
        for (int i = head[u]; i; i = e[i].ne) {
            int v = e[i].v;
            if (dis[v] > dis[u] + e[i].c) {
                dis[v] = dis[u] + e[i].c;
                que.push(std::pii(dis[v], v));
            }
        }
    }
    return dis[t];
}

int main() {
    IO::read(n, m);
    int s = 1, t = 2;
    tol = 2;
    for (int i = 1; i < n; i++)
        for (int j = 1; j < m; j++)
            id[i][j][0] = ++tol, id[i][j][1] = ++tol;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j < m; j++) {
            int u, v;
            if (i == n) u = s;
            else u = id[i][j][1];
            if (i == 1) v = t;
            else v = id[i - 1][j][0];
            int c;
            IO::read(c);
            add(u, v, c);
        }
    for (int i = 1; i < n; i++)
        for (int j = 1; j <= m; j++) {
            int u, v;
            if (j == 1) u = s;
            else u = id[i][j - 1][1];
            if (j == m) v = t;
            else v = id[i][j][0];
            int c;
            IO::read(c);
            add(u, v, c);
        }
    for (int i = 1; i < n; i++)
        for (int j = 1; j < m; j++) {
            int u = id[i][j][0], v = id[i][j][1];
            int c;
            IO::read(c);
            add(u, v, c);
        }
    printf("%d\n", dijkstra(s, t));
    return 0;
}
View Code

 

posted @ 2020-01-25 22:19  Mrzdtz220  阅读(117)  评论(0编辑  收藏  举报