HDU - 2732 Leapin' Lizards(ISAP Dinic EK)

来源:互联网 发布:windows无法识别音响 编辑:程序博客网 时间:2024/06/05 16:24

题目大意:给出两张地图,第一张地图代表的是每根柱子的高度,第二张地图代表的是每只蜥蜴所在的位置
每根柱子只能站一只蜥蜴,蜥蜴离开该柱子时,柱子的高度会下降一个单元,当柱子的高度为0时,该柱子将不可用
现在给出每只蜥蜴能跳跃的距离,问最少有多少只蜥蜴逃不出来

解题思路:将柱子拆成2个点,权值为柱子的高度
将每只蜥蜴所在的位置和超级源点连接,权值为1
将能通到外界的柱子连接到超级汇点,权值为INF
如果柱子间的距离满足蜥蜴跳跃的距离,连接起来,权值为INF
这样图就完成了

ISAP:

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 2010#define INF 0x3f3f3f3fstruct Edge {    int from, to, cap, flow;    Edge() {}    Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow) {}};struct ISAP {    int p[N], num[N], cur[N], d[N];    int t, s, n, m;    bool vis[N];    vector<int> G[N];    vector<Edge> edges;    void init(int n, int m) {        this->n = n; this->m = m;        for (int i = 0; i <= n; i++) {            G[i].clear();            d[i] = INF;        }        edges.clear();    }    void AddEdge(int from, int to, int cap) {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        int m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool BFS() {        memset(vis, 0, sizeof(vis));        queue<int> Q;        d[t] = 0;        vis[t] = 1;        Q.push(t);        while (!Q.empty()) {            int u = Q.front();            Q.pop();            for (int i = 0; i < G[u].size(); i++) {                Edge &e = edges[G[u][i] ^ 1];                if (!vis[e.from] && e.cap > e.flow) {                    vis[e.from] = true;                    d[e.from] = d[u] + 1;                    Q.push(e.from);                }            }        }        return vis[s];    }    int Augment() {        int u = t, flow = INF;        while (u != s) {            Edge &e = edges[p[u]];            flow = min(flow, e.cap - e.flow);            u = edges[p[u]].from;        }        u = t;        while (u != s) {            edges[p[u]].flow += flow;            edges[p[u] ^ 1].flow -= flow;            u = edges[p[u]].from;        }        return flow;    }    int Maxflow(int s, int t) {        this->s = s; this->t = t;        int flow = 0;        BFS();        if (d[s] > n)            return 0;        memset(num, 0, sizeof(num));        memset(cur, 0, sizeof(cur));        for (int i = 0; i < n; i++)            if (d[i] < INF)                num[d[i]]++;        int u = s;        while (d[s] <= n) {            if (u == t) {                flow += Augment();                u = s;            }            bool ok = false;            for (int i = cur[u]; i < G[u].size(); i++) {                Edge &e = edges[G[u][i]];                if (e.cap > e.flow && d[u] == d[e.to] + 1) {                    ok = true;                    p[e.to] = G[u][i];                     cur[u] = i;                    u = e.to;                    break;                }            }            if (!ok) {                int Min = n;                for (int i = 0; i < G[u].size(); i++) {                    Edge &e = edges[G[u][i]];                    if (e.cap > e.flow)                        Min = min(Min, d[e.to]);                }                if (--num[d[u]] == 0)                    break;                num[d[u] = Min + 1]++;                cur[u] = 0;                if (u != s)                    u = edges[p[u]].from;            }        }        return flow;    }};ISAP isap;#define M 110#define ABS(x) ((x) > 0 ? x : (-(x)))#include <cstring>char map1[25][M], map2[25][M];int n, d, m, cas = 1;void init() {    scanf("%d%d", &n, &d);    for (int i = 0; i < n; i++)        scanf("%s", map1[i]);    for (int i = 0; i < n; i++)        scanf("%s", map2[i]);    m = strlen(map1[0]);    int s = n * m * 2, t = s + 1;    isap.init(t, 0);    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)             if (map1[i][j] - '0') {                isap.AddEdge(i * m + j, n * m + i * m + j, map1[i][j] - '0');            }    int cnt = 0;    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            if (map2[i][j] == 'L') {                isap.AddEdge(s, i * m + j, 1);                cnt++;            }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++) {            if (i < d || j < d || j >= m - d || i >= n - d) {                isap.AddEdge(i * m + j + n * m, t, INF);            }        }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            for (int k = 0; k < n; k++)                for (int l = 0; l < m; l++)                    if (!(i == k && l == m) && d >= ABS(i - k) + ABS(j - l))                        isap.AddEdge(i * m + j + n * m, k * m + l, INF);    int ans = isap.Maxflow(s, t);    printf("Case #%d: ", cas++);    if (ans == cnt)         printf("no lizard was left behind.\n");    else if(ans + 1 == cnt)        printf("1 lizard was left behind.\n");    else         printf("%d lizards were left behind.\n", cnt - ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();    }    return 0;}

EK

#include <cstdio>#include <cstring>#include <queue>#include <algorithm>#include <vector>using namespace std;#define N 1010#define INF 0x3f3f3f3fstruct Edge{    int from, to, cap, flow;    Edge() {}    Edge(int from, int to, int cap, int flow): from(from), to(to), cap(cap), flow(flow){}};struct EK{    vector<int> G[N];    vector<Edge> edges;    int s, t, n, m, p[N];    bool vis[N];    void init(int n, int m) {        this->n = n; this->m = m;        for (int i = 0; i <= n; i++)            G[i].clear();        edges.clear();    }    void AddEdge(int from, int to, int cap) {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        int m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }    bool BFS() {        queue<int> q;        memset(vis, 0, sizeof(vis));        vis[s] = 1;        q.push(s);        while (!q.empty()) {            int u = q.front();            q.pop();            for (int i = 0; i < G[u].size(); i++) {                Edge &e = edges[G[u][i]];                if (!vis[e.to] && e.cap > e.flow) {                    vis[e.to] = true;                    p[e.to] = G[u][i];                    if (e.to == t)                        return true;                    q.push(e.to);                }            }        }        return false;    }    int Augment() {        int flow = INF, u = t;        while (u != s) {            Edge &e = edges[p[u]];            flow = min(flow, e.cap - e.flow);            u = e.from;        }        u = t;        while (u != s) {            edges[p[u]].flow += flow;            edges[p[u] ^ 1].flow -= flow;            u = edges[p[u]].from;        }        return flow;    }    int Maxflow(int s, int t) {        this->s = s; this->t = t;        int flow = 0;        while (BFS()) {            flow += Augment();        }        return flow;    }};EK ek;#define M 110#define ABS(x) ((x) > 0 ? x : (-(x)))#include <cstring>char map1[25][M], map2[25][M];int n, d, m, cas = 1;void init() {    scanf("%d%d", &n, &d);    for (int i = 0; i < n; i++)        scanf("%s", map1[i]);    for (int i = 0; i < n; i++)        scanf("%s", map2[i]);    m = strlen(map1[0]);    int s = n * m * 2, t = s + 1;    ek.init(t, 0);    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)             if (map1[i][j] - '0') {                ek.AddEdge(i * m + j, n * m + i * m + j, map1[i][j] - '0');            }    int cnt = 0;    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            if (map2[i][j] == 'L') {                ek.AddEdge(s, i * m + j, 1);                cnt++;            }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++) {            if (i < d || j < d || j >= m - d || i >= n - d) {                ek.AddEdge(i * m + j + n * m, t, INF);            }        }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            for (int k = 0; k < n; k++)                for (int l = 0; l < m; l++)                    if (!(i == k && l == m) && d >= ABS(i - k) + ABS(j - l))                        ek.AddEdge(i * m + j + n * m, k * m + l, INF);    int ans = ek.Maxflow(s, t);    printf("Case #%d: ", cas++);    if (ans == cnt)         printf("no lizard was left behind.\n");    else if(ans + 1 == cnt)        printf("1 lizard was left behind.\n");    else         printf("%d lizards were left behind.\n", cnt - ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();    }    return 0;}

Dinic

#include <cstdio>#include <cstring>#include <algorithm>#include <vector>#include <queue>using namespace std;#define N 1010#define INF 0x3f3f3f3fstruct Edge{    int from, to, cap, flow;    Edge() {}    Edge(int from, int to, int cap, int flow) : from(from), to(to), cap(cap), flow(flow) {}};struct Dinic{    int n, m, s, t;    vector<Edge> edges;    vector<int> G[N];    bool vis[N];    int d[N], cur[N];    void init(int n, int m) {        this->n = n; this->m = m;        for (int i = 0; i <= n; i++) {            G[i].clear();        }        edges.clear();    }    void AddEdge(int from, int to, int cap) {        edges.push_back(Edge(from, to, cap, 0));        edges.push_back(Edge(to, from, 0, 0));        int m = edges.size();        G[from].push_back(m - 2);        G[to].push_back(m - 1);    }     bool BFS() {        memset(vis, 0, sizeof(vis));        queue<int> Q;        Q.push(s);        vis[s] = 1;        d[s] = 0;        while (!Q.empty()) {            int u = Q.front();            Q.pop();            for (int i = 0; i < G[u].size(); i++) {                Edge &e = edges[G[u][i]];                if (!vis[e.to] && e.cap > e.flow) {                    vis[e.to] = true;                    d[e.to] = d[u] + 1;                    Q.push(e.to);                }            }        }        return vis[t];    }    int DFS(int x, int a) {        if (x == t || a == 0)            return a;        int flow = 0, f;        for (int i = cur[x]; i < G[x].size(); i++) {            Edge &e = edges[G[x][i]];            if (d[x] + 1 == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > 0) {                e.flow += f;                edges[G[x][i] ^ 1].flow -= f;                flow += f;                a -= f;                if (a == 0)                    break;            }        }        return flow;    }    int Maxflow(int s, int t) {        this->s = s; this->t = t;        int flow = 0;        while (BFS()) {            memset(cur, 0, sizeof(cur));            flow += DFS(s, INF);        }        return flow;    }};Dinic dinic;#define M 110#define ABS(x) ((x) > 0 ? x : (-(x)))#include <cstring>char map1[25][M], map2[25][M];int n, d, m, cas = 1;void init() {    scanf("%d%d", &n, &d);    for (int i = 0; i < n; i++)        scanf("%s", map1[i]);    for (int i = 0; i < n; i++)        scanf("%s", map2[i]);    m = strlen(map1[0]);    int s = n * m * 2, t = s + 1;    dinic.init(t, 0);    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)             if (map1[i][j] - '0') {                dinic.AddEdge(i * m + j, n * m + i * m + j, map1[i][j] - '0');            }    int cnt = 0;    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            if (map2[i][j] == 'L') {                dinic.AddEdge(s, i * m + j, 1);                cnt++;            }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++) {            if (i < d || j < d || j >= m - d || i >= n - d) {                dinic.AddEdge(i * m + j + n * m, t, INF);            }        }    for (int i = 0; i < n; i++)        for (int j = 0; j < m; j++)            for (int k = 0; k < n; k++)                for (int l = 0; l < m; l++)                    if (!(i == k && l == m) && d >= ABS(i - k) + ABS(j - l))                        dinic.AddEdge(i * m + j + n * m, k * m + l, INF);    int ans = dinic.Maxflow(s, t);    printf("Case #%d: ", cas++);    if (ans == cnt)         printf("no lizard was left behind.\n");    else if(ans + 1 == cnt)        printf("1 lizard was left behind.\n");    else         printf("%d lizards were left behind.\n", cnt - ans);}int main() {    int test;    scanf("%d", &test);    while (test--) {        init();    }    return 0;}
0 0
原创粉丝点击