Gym - 101128F Landscaping(网络流)
题意
给你一个\(N×M\)的草地,有高地有低地。
收割机从低地走到高地或者从高地走到低地都要花费用\(A\),你可以花费用\(B\)把一块高地变成低地,或者把一块低地变成高地。收割机每行每列都是必须要跑一趟的。
求最小花费。

解析
\(S\)向低地、高地向\(T\)建权为\(B\)的边,相邻的地之间建边权为\(A\)的边。
然后求最小割。
相同类型的地之间为什么也要建边呢?因为类型是可以改变的。
#include <bits/stdc++.h>
#define FOPI freopen("in.txt", "r", stdin)
#define FOPO freopen("out.txt", "w", stdout)
using namespace std;
typedef long long LL;
const int inf = 0x3f3f3f3f;
const int maxn = 50 * 50 + 1000;
const int maxm = 1e5 + 100;
struct Edge
{
    int to, next, cap, flow;
}edge[maxm];
int tot;
int head[maxn];
void init()
{
    tot = 2;
    memset(head, -1, sizeof(head));
}
void build(int u, int v, int w, int rw = 0)
{
    edge[tot].to = v; edge[tot].cap = w; edge[tot].flow = 0;
    edge[tot].next = head[u]; head[u] = tot++;
    edge[tot].to = u; edge[tot].cap = 0; edge[tot].flow = 0;
    edge[tot].next = head[v]; head[v] = tot++;
}
int Q[maxn];
int dep[maxn], cur[maxn], sta[maxn];
bool bfs(int s, int t, int n)
{
    int front = 0, tail = 0;
    memset(dep, -1, sizeof(dep[0]) * (n+1));
    dep[s] = 0;
    Q[tail++] = s;
    while(front < tail)
    {
        int u = Q[front++];
        for (int i = head[u]; i != -1; i = edge[i].next)
        {
            int v = edge[i].to;
            if (edge[i].cap > edge[i].flow && dep[v] == -1)
            {
                dep[v] = dep[u] + 1;
                if (v == t) return true;
                Q[tail++] = v;
            }
        }
    }
    return false;
}
LL dinic(int s, int t, int n)
{
    LL maxflow = 0;
    while(bfs(s, t, n))
    {
        for (int i = 0; i < n; i++) cur[i] = head[i];
        int u = s, tail = 0;
        while(cur[s] != -1)
        {
            if (u == t)
            {
                int tp = inf;
                for (int i = tail-1; i >= 0; i--)
                    tp = min(tp, edge[sta[i]].cap - edge[sta[i]].flow);
                //if (tp >= inf) return -1;
                maxflow += tp;
                for (int i = tail-1; i >= 0; i--)
                {
                    edge[sta[i]].flow += tp;
                    edge[sta[i]^1].flow -= tp;
                    if (edge[sta[i]].cap - edge[sta[i]].flow == 0) tail = i;
                }
                u = edge[sta[tail]^1].to;
            }
            else if (cur[u] != -1 && edge[cur[u]].cap > edge[cur[u]].flow
                     && dep[u]+1 == dep[edge[cur[u]].to])
            {
                sta[tail++] = cur[u];
                u = edge[cur[u]].to;
            }
            else
            {
                while(u != s && cur[u] == -1) u = edge[sta[--tail]^1].to;
                cur[u] = edge[cur[u]].next;
            }
        }
    }
    return maxflow;
}
int n, m, A, B;
int S, T;
char a[maxn][maxn];
int id(int i, int j) { return (i-1)*m + j; }
int main()
{
    //FOPI;
    init();
    scanf("%d%d%d%d", &n, &m, &A, &B);
    S = 0, T = n*m+1;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= m; j++)
        {
            scanf(" %c", &a[i][j]);
            if (a[i][j] == '.') build(S, id(i, j), B);
                else build(id(i, j), T, B);
            if (i > 1) build(id(i, j), id(i-1, j), A);
            if (i < n) build(id(i, j), id(i+1, j), A);
            if (j > 1) build(id(i, j), id(i, j-1), A);
            if (j < m) build(id(i, j), id(i, j+1), A);
        }
    LL ans = dinic(S, T, T+1);
    printf("%lld\n", ans);
}
Gym - 101128F Landscaping(网络流)的更多相关文章
- Gym 101128F Landscaping(网络流)题解
		题意:n*m的地,从有高地和低地,从高地走到低地或者从低地走到高地花费a,把高地和低地互相改造一次花费b.现在要走遍每一行每一列,问最小花费 思路:超级源点连接所有低地,容量b:所有地向四周建边,容量 ... 
- 【最小割】【Dinic】Gym - 101128F  - Landscaping
		http://blog.csdn.net/lxy767087094/article/details/68942422 #include<cstdio> #include<cstrin ... 
- Landscaping Gym - 101128F (网络流)
		Problem F: Landscaping \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 题意是给出一个\(n*m\)的格子,其中一些是低 ... 
- Gym 101128F Sheldon Numbers(网络流)
		[题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ... 
- C - Portals Gym - 102006C (网络流最小割)
		题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ... 
- 【bzoj4439】[Swerc2015]Landscaping  网络流最小割
		题目描述 FJ有一块N*M的矩形田地,有两种地形高地(用‘#’表示)和低地(用‘.’表示) FJ需要对每一行田地从左到右完整开收割机走到头,再对每一列从上到下完整走到头,如下图所示 对于一个4*4的田 ... 
- codeforces gym 100357 J (网络流)
		题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ... 
- Gym 102007I 二分 网络流
		题意:给你一张图,每个城市有一些人,有不超过10个城市有避难所,避难所有容量上限,问最快多久可以让所有人进入避难所? 思路:二分时间,对于每个时间跑一遍最大流,判断最大流是不是人数即可.我们还需要用二 ... 
- Gym - 100203I  I WIN  网络流
		Gym - 100203I I WIN 题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN. 思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下 ... 
随机推荐
- GitLab常用命令整理
			进入本地仓库访问位置之后执行命令 1) 远程仓库相关命令 检出仓库:$ git clone git://github.com/jquery/jquery.git 查看远程仓库:$ git remote ... 
- String与Date转换
			public class TimeTraining { public static void changeStr(String str){ str = "137878"; } pu ... 
- JAVA 与 sqlite3 连接
			SQLite SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中.它是D.RichardHipp建立的公有领域项目.它的设计目标是嵌入式的,而且目前已经 ... 
- sql server 搭建发布订阅后,改端口不正常工作的问题
			sql 的发布订阅,想必大家都了解,但一般都是在默认的1433的情况下搭建的,那么1433换成别的端口,发布还能正常工作吗? 在一次客户的真实场景上我就遇到了. 好了,今天不想写太多,简化下, 测试环 ... 
- jQuery-添加新元素的方法(append()、prepend()、before()、after())
			1.以 HTML 创建新元素 var txt1="<p>Text.</p>"; 2.以 jQuery 创建新元素 var txt2=$("< ... 
- 利用photoshop制作gif图片
			首先准备你需要的几张素材图片 1.将素材图片根据发生的顺序放置在不同的图层 2.打开窗口下的时间轴 选择帧动画 3.创建第一张帧动画 选项卡右边这个按钮,点击这个选择新建帧 第一张图片显示其他的隐藏 ... 
- .Net创建Windows服务完成批量导出功能(错误速查)
			无法打开计算机“.”上的服务控制管理器.此操作可能需要其他特权. 无法将类型为“Microsoft.Office.Interop.Word.ApplicationClass”的 COM 对象强制转换为 ... 
- IBM WebSphere MQ安装及配置详解
			打开MQ安装程序,选择下一步,默认安装WebSphere MQ, 完成MQ的安装工作,启动WebSphere MQ, 服务器配置,选择新建队列管理器,创建名为 "mq"的队列管理器 ... 
- 用ComboBox控件制作浏览器网址输入框
			实现效果: 知识运用: ComboBox控件的FindString public int FindString(string s) //查找数据项集合中指定数据项的索引 和Select方法 publi ... 
- Symfony相关网站参考
			http://www.doctrine-project.org/projects.html 数据库相关知识 http://firehare.blog.51cto.com/809276/703599整合 ... 
