BZOJ2007——[Noi2010]海拔

来源:互联网 发布:canny边缘检测算法fpga 编辑:程序博客网 时间:2024/04/28 08:04

1、题意:一个裸的最小割

2、分析:直接转成对偶图最短路就好了,水爆了!(雾)

#include <queue>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>using namespace std;#define M 2000010#define inf 1014748364 inline int read(){    char ch = getchar(); int x = 0, f = 1;    while(ch < '0' || ch > '9'){        if(ch == '-') f = -1;        ch = getchar();    }    while('0' <= ch && ch <= '9'){        x = x * 10 + ch - '0';        ch = getchar();    }    return x * f;}  namespace dijkstra{    struct Edge{        int u, v, w, next;    } G[M];    int head[M], tot;         struct Node{        int d, u;                 inline bool operator < (const Node& rhs) const{            return d > rhs.d;        }    };    priority_queue<Node> Q;    int d[M];    bool done[M];         inline void init(){        memset(head, -1, sizeof(head));        tot = 0;    }         inline void add(int u, int v, int w){    //  printf("%d %d %d\n", u, v, w);        G[++ tot] = (Edge){u, v, w, head[u]};        head[u] = tot;    }         inline int get_dis(int s, int t, int n){        memset(done, 0, sizeof(done));        for(int i = 0; i <= n; i ++) d[i] = inf;        d[s] = 0;        Q.push((Node){0, s});        while(!Q.empty()){            Node u = Q.top(); Q.pop();            int x = u.u;            if(done[x]) continue;            done[x] = 1;            for(int i = head[x]; i != -1; i = G[i].next){                Edge& e = G[i];                if(d[e.v] > d[x] + e.w){                    d[e.v] = d[x] + e.w;                    Q.push((Node){d[e.v], e.v});                }            }        }        return d[t];    }} using namespace dijkstra; int n; inline int num(int i, int j){    if(j < 1 || i > n) return 0;    if(i < 1 || j > n) return n * n + 1;    return (i - 1) * n + j; } int main(){    n = read();    init();    for(int i = 0; i <= n; i ++){        for(int j = 1; j <= n; j ++){            int x = read();            add(num(i + 1, j), num(i, j), x);        }    }    for(int i = 1; i <= n; i ++){        for(int j = 0; j <= n; j ++){            int x = read();            add(num(i, j), num(i, j + 1), x);        }    }    for(int i = 0; i <= n; i ++){        for(int j = 1; j <= n; j ++){            int x = read();            add(num(i, j), num(i + 1, j), x);        }    }    for(int i = 1; i <= n; i ++){        for(int j = 0; j <= n; j ++){            int x = read();            add(num(i, j + 1), num(i, j), x);        }    }    printf("%d\n", get_dis(0, n * n + 1, n * n + 1));    return 0;}


0 0
原创粉丝点击