打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
BZOJ1001或洛谷4001 [BJOI2006]狼抓兔子

显然就是求最小割。
而对于一个平面图有结论,最大流=最小割=对偶图最短路。
所以这题可用最大流或是转换为对偶图求最短路,这里我是用的对偶图。
虽然理论上按上界算,这题\(Dinic\)应该是跑不过去的,不过因为网络流复杂度玄学,\(Dinic\)莫名跑得挺快的。
在转换对偶图的时候,注意\(n = 1\)或\(m = 1\)的情况。

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int N = 2e6   10;const int M = 7e6   10;struct po {    int x, d;    bool operator < (const po &b) const    {        return d > b.d;    }};po X;int fi[N], di[M], ne[M], da[M], dis[N], l, st, ed, n, m;bool v[N];priority_queue<po>q;inline int re(){    int x = 0;    char c = getchar();    bool p = 0;    for (; c < '0' || c > '9'; c = getchar())        p |= c == '-';    for (; c >= '0' && c <= '9'; c = getchar())        x = x * 10   c - '0';    return p ? -x : x;}inline void add(int x, int y, int z){    di[  l] = y;    da[l] = z;    ne[l] = fi[x];    fi[x] = l;    di[  l] = x;    da[l] = z;    ne[l] = fi[y];    fi[y] = l;}inline int ch(int x, int y, int L){    int k = ((x - 1) * (m - 1)   y) << 1;    return L ? k - 1 : k;}inline void add_row(int x, int y, int z){    if (!(x ^ 1))        add(ch(x, y, 0), ed, z);    else        if (!(x ^ n))            add(st, ch(x - 1, y, 1), z);        else            add(ch(x - 1, y, 1), ch(x, y, 0), z);}inline void add_col(int x, int y, int z){    if (!(y ^ 1))        add(st, ch(x, y, 1), z);    else        if (!(y ^ m))            add(ch(x, y - 1, 0), ed, z);        else            add(ch(x, y - 1, 0), ch(x, y, 1), z);}inline void add_opl(int x, int y, int z){    add(ch(x, y, 1), ch(x, y, 0), z);}int main(){    int i, j, x, y;    n = re();    m = re();    st = (n - 1) * (m - 1) << 1 | 1;    ed = st   1;    if (!(n ^ 1) || !(m ^ 1))    {        for (i = 1; i <= n; i  )            for (j = 1; j < m; j  )                add(st, ed, re());        for (i = 1; i < n; i  )            for (j = 1; j <= m; j  )                add(st, ed, re());        for (i = 1; i < n; i  )            for (j = 1; j < m; j  )                add(st, ed, re());    }    else    {        for (i = 1; i <= n; i  )            for (j = 1; j < m; j  )                add_row(i, j, re());        for (i = 1; i < n; i  )            for (j = 1; j <= m; j  )                add_col(i, j, re());        for (i = 1; i < n; i  )            for (j = 1; j < m; j  )                add_opl(i, j, re());    }    memset(dis, 60, sizeof(dis));    X.d = dis[X.x = st] = 0;    q.push(X);    while (!q.empty())    {        x = q.top().x;        q.pop();        if (v[x])            continue;        v[x] = 1;        for (i = fi[x]; i; i = ne[i])            if (dis[X.x = y = di[i]] > dis[x]   da[i])            {                X.d = dis[y] = dis[x]   da[i];                q.push(X);            }    }    printf("%d", dis[ed]);    return 0;}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【洛谷日报#230】 网络流常见模型:有限制的图上最短(长)路
函数实现不放在头文件的原因,及何时可以放头文件的情况
262 操作符
当我print时,Python做了什么
stl:: pair源码以及使用
C语言实现的list
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服