洛谷 P4001

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_40924940/article/details/84330704

这道题 就是求最小割,看着比较简单明了,

那么我们根据 最大流 = 最小割原理,求出最大流 就好了。。。

但是这道题 有一个问题

数据还是很玄学的,需要 dinic 先 bfs 对图进行一下分层,而且还需要一定的剪枝,如果 dinic 的时候有一条路找不到终点,很显然这条路已经没意义了,我们就给这条路堵上。。开始 最后几个点似乎就卡在这里了。。

这道题可以当 dinic 模板 看一看

以下是 AC 代码。。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
#define ll long long int
const int INF = 0x3ffff;
const int maxn = 1e6+5;
ll head[maxn],cnt;
ll h[maxn],q[maxn];
ll st, en, anss;
ll n,m;
struct node
{
    ll to,fr;
    ll flow;
    ll next;
}e[maxn*6];
void add(ll u, ll v, ll w)
{
    e[cnt].fr = u, e[cnt].to = v, e[cnt].flow = w;
    e[cnt].next = head[u], head[u] = cnt++;
    e[cnt].fr = v, e[cnt].to = u, e[cnt].flow = w;
    e[cnt].next = head[v], head[v] = cnt++;
}
bool bfs()
{
    queue<int>q;
    memset(h,0,sizeof(h));
    h[st] = 1;
    q.push(st);
    while(q.size())
    {
        int now = q.front();
        q.pop();
        for(int i=head[now]; i!=-1; i=e[i].next)
        {
            int t = e[i].to;
            if(h[t] == 0 && e[i].flow > 0)
            {
                h[t] = h[now] + 1;
                q.push(e[i].to);
            }
        }
    }
    return h[en];
}
ll dfs(int u, int flow)
{
    if(u == en)
        return flow;
    ll add = 0;
    for(int i=head[u]; i != -1 && add < flow; i=e[i].next)
    {
        int v = e[i].to;
        if(h[v] != h[u] + 1 || !e[i].flow)
            continue;
        int temp = dfs(v, min(e[i].flow, flow - add));
        if(!temp)
        {
            h[v] = -1;
            continue;
        }
        e[i].flow -= temp;
        e[i ^ 1].flow += temp;
        add += temp;
    }
    return add;
}
void dinic()
{
    while(bfs())
        anss += dfs(st, INF);
}
int gethash(int i, int j)
{
    return (i - 1) * m + j;
}
int main()
{
    memset(head,-1,sizeof(head));
    cin>>n>>m;
    st = 1,en = n * m;
    anss = 0 ,cnt = 0;
    ll tmp;
    for(int i = 1; i <= n; ++i)
    {
        for(int j = 1; j < m; ++j)
        {
            cin>>tmp;
            add(gethash(i, j), gethash(i, j + 1), tmp);
        }
    }
    for(int i = 1; i < n; ++i)
    {
        for(int j = 1; j <= m; ++j)
        {
            cin>>tmp;
            add(gethash(i, j), gethash(i + 1, j), tmp);
        }
    }
    for(int i = 1; i < n; ++i)
    {
        for(int j = 1; j < m; ++j)
        {
            cin>>tmp;
            add(gethash(i, j), gethash(i + 1, j + 1), tmp);
        }
    }
    dinic();
    cout<<anss<<endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40924940/article/details/84330704
今日推荐