码迷,mamicode.com
首页 > 其他好文 > 详细

BZOJ 1001 [BeiJing2006]狼抓兔子

时间:2015-12-23 21:18:20      阅读:206      评论:0      收藏:0      [点我收藏+]

标签:

这题算是平面图上最大流/最小割比较经典的一题了吧。。

 

周冬的论文《两极相通——浅析最大最小定理在信息学竞赛中的应用》中给出了详细的解释和证明。

平面图上的最大流/最小割等于它对偶图上的最短路(大致是这个意思吧)。

把每个三角形作为点,有公共边就连边,有上边界和右边界的与源点连边,有左边界或下边界的与终点连边,然后跑一遍最短路即可。

注意n=1和m=1的情况要特判!

 

技术分享
#include <queue>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>

using namespace std;

const size_t Max_V(2000050);
const size_t Max_E(6000050);
const unsigned int Up(1), Down(2);
typedef pair<unsigned int, size_t> pil;

void Get_Val(unsigned int &ret)
{
    ret = 0;
    char ch;
    while ((ch = getchar()), (ch > 9 || ch < 0))
        ;
    do
    {
        (ret *= 10) += ch - 0;
    }
    while ((ch = getchar()), (ch >= 0 && ch <= 9));
}

void Special(const unsigned int &a)
{
    unsigned int Ans(0X7F7F7F7FU);
    unsigned int Temp;
    for (unsigned int flag = 1;flag != a;++flag)
    {
        Get_Val(Temp);
        Ans = min(Ans, Temp);
    }
    printf("%u", Ans);
}

size_t N, M;
size_t S, T;
unsigned int Total;
unsigned int Head[Max_V];
unsigned int To[Max_E], Next[Max_E], Weight[Max_E];

inline
unsigned int Get_Point(const size_t &i, const size_t &j, const unsigned int &location)
{
    return (((i - 1) * M + j - 1) << 1) + location;
}

inline
void Add_Edge(const size_t &s, const size_t &t, const unsigned int &w)
{
    ++Total;
    To[Total] = t, Weight[Total] = w;
    Next[Total] = Head[s], Head[s] = Total;
}

void init()
{
    Get_Val(N), Get_Val(M);
    unsigned int w;
    if (N == 1)
    {
        Special(M);
        exit(0);
    }
    if (M == 1)
    {
        Special(N);
        exit(0);
    }
    --N, --M;
    S = (N * M << 1) + 1;
    T = (N * M << 1) + 2;
    for (size_t i = 0;i <= N;++i)
        for (size_t j = 1;j <= M;++j)
        {
            Get_Val(w);
            if (i == 0)
            {
                Add_Edge(Get_Point(1, j, Up), S, w);
                Add_Edge(S, Get_Point(1, j, Up), w);
                continue;
            }
            if (i == N)
            {
                Add_Edge(Get_Point(N, j, Down), T, w);
                Add_Edge(T, Get_Point(N, j, Down), w);
                continue;
            }
            Add_Edge(Get_Point(i, j, Down), Get_Point(i + 1, j, Up), w);
            Add_Edge(Get_Point(i + 1, j, Up), Get_Point(i, j, Down), w);
        }
    for (size_t i = 1;i <= N;++i)
        for (size_t j = 0;j <= M;++j)
        {
            Get_Val(w);
            if (j == 0)
            {
                Add_Edge(Get_Point(i, 1, Down), T, w);
                Add_Edge(T, Get_Point(i, 1, Down), w);
                continue;
            }
            if (j == M)
            {
                Add_Edge(Get_Point(i, j, Up), S, w);
                Add_Edge(S, Get_Point(i, j, Up), w);
                continue;
            }
            Add_Edge(Get_Point(i, j, Up), Get_Point(i, j + 1, Down), w);
            Add_Edge(Get_Point(i, j + 1, Down), Get_Point(i, j, Up), w);
        }
    for (size_t i = 1;i <= N;++i)
        for (size_t j = 1;j <= M;++j)
        {
            Get_Val(w);
            Add_Edge(Get_Point(i, j, Up), Get_Point(i, j, Down), w);
            Add_Edge(Get_Point(i, j, Down), Get_Point(i, j, Up), w);
        }
}

unsigned int Dist[Max_V];
bool Done[Max_V];
unsigned int dijkstra()
{
    memset(Dist, 0X7F, sizeof(Dist));
    priority_queue<pil, vector<pil>, greater<pil> > Q;
    Dist[S] = 0;
    Q.push(pil(0, S));
    size_t Top;
    while (Q.size())
    {
        Top = Q.top().second;
        Q.pop();
        if (Done[Top])
            continue;
        Done[Top] = true;
        for (size_t i = Head[Top];i;i = Next[i])
            if (Dist[To[i]] > Dist[Top] + Weight[i])
            {
                Dist[To[i]] = Dist[Top] + Weight[i];
                Q.push(pil(Dist[To[i]], To[i]));
            }
    }
    return Dist[T];
}

int main()
{
    init();
    printf("%u", dijkstra());
    
    return 0;
}
BZOJ 1001

 

BZOJ 1001 [BeiJing2006]狼抓兔子

标签:

原文地址:http://www.cnblogs.com/Created-equal/p/5071154.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!