Codeforces Gym101518H:No Smoking, Please(最小割)
题意
给出一个n*m的酒店,每个点是一个房间,要将这个酒店的房间划分成为两块(一块无烟区,一块吸烟区),相邻的两个房间之间有一条带权边,权值代表空气锁的面积,如果把这条边给去掉,那么需要花费(空气锁的面积+开一个窗口传食物)*1000元。问需要的最少花费是多少。要注意如果面积为0,则这条边不能划分。
思路
全场做的人不多,主要看题意比较难,看懂题意就会发现是裸的最小割,但是有个面积为0的坑点。这里的边需要开的比较大,考虑到每次增加两个点,就会使边增加三条(不知道这样想对不对),于是就开两倍(还有两倍双向边)。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef pair<int, int> pii;
const int INF = 0x3f3f3f3f;
const int M = 1e3 + 11;
const int N = 1e6 + 11;
struct Edge {
int u, v, nxt, cap;
} edge[N*4];
int head[N], tot, id[M][M];
int cur[N], gap[N], dis[N], pre[N];
queue<int> que;
void Add(int u, int v, int cap) {
edge[tot] = (Edge) { u, v, head[u], cap }; head[u] = tot++;
edge[tot] = (Edge) { v, u, head[v], cap }; head[v] = tot++;
}
void BFS(int T) {
while(!que.empty()) que.pop();
memset(dis, INF, sizeof(dis));
memset(gap, 0, sizeof(gap));
gap[0] = 1; dis[T] = 0;
que.push(T);
while(!que.empty()) {
int u = que.front(); que.pop();
for(int i = head[u]; ~i; i = edge[i].nxt) {
int v = edge[i].v;
if(dis[v] != INF) continue;
dis[v] = dis[u] + 1;
gap[dis[v]]++;
que.push(v);
}
}
}
int ISAP(int S, int T, int n) {
BFS(T);
memcpy(cur, head, sizeof(cur));
int i, flow, u = pre[S] = S, index, ans = 0;
while(dis[S] < n) {
if(u == T) {
flow = INF, index = u;
for(u = S; u != T; u = edge[cur[u]].v)
if(edge[cur[u]].cap < flow) flow = edge[cur[u]].cap, index = u;
for(u = S; u != T; u = edge[cur[u]].v)
edge[cur[u]].cap -= flow, edge[cur[u]^1].cap += flow;
u = index, ans += flow;
}
for(i = cur[u]; ~i; i = edge[i].nxt)
if(dis[edge[i].v] == dis[u] - 1 && edge[i].cap) break;
if(~i) {
pre[edge[i].v] = u; cur[u] = i; u = edge[i].v;
} else {
if(--gap[dis[u]] == 0) break;
int md = n + 1;
for(i = head[u]; ~i; i = edge[i].nxt)
if(edge[i].cap && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
gap[dis[u] = md + 1]++;
u = pre[u];
}
} return ans;
}
int main() {
int t; scanf("%d", &t);
while(t--) {
memset(head, -1, sizeof(head));
tot = 0;
int n, m, sx, sy, ex, ey;
scanf("%d%d", &n, &m);
scanf("%d%d%d%d", &sx, &sy, &ex, &ey);
int cnt = 0;
for(int i = 0; i < n; i++)
for(int j = 0; j < m; j++) id[i][j] = ++cnt;
for(int i = 0; i < n; i++) {
for(int j = 0; j < m - 1; j++) {
int cap; scanf("%d", &cap);
if(cap) Add(id[i][j], id[i][j+1], cap + 1);
}
}
for(int i = 0; i < n - 1; i++) {
for(int j = 0; j < m; j++) {
int cap; scanf("%d", &cap);
if(cap) Add(id[i][j], id[i+1][j], cap + 1);
}
}
printf("%d\n", ISAP(id[sx][sy], id[ex][ey], n * m) * 1000);
} return 0;
}
Codeforces Gym101518H:No Smoking, Please(最小割)的更多相关文章
- Codeforces 724E Goods transportation(最小割转DP)
[题目链接] http://codeforces.com/problemset/problem/724/E [题目大意] 每个城市有pi的物品可以运出去卖,si个物品可以买, 编号小的城市可以往编号大 ...
- Codeforces 1368H - Breadboard Capacity(最小割+线段树维护矩阵乘法)
Easy version:Codeforces 题面传送门 & 洛谷题面传送门 Hard version:Codeforces 题面传送门 & 洛谷题面传送门 首先看到这种从某一种颜色 ...
- Codeforces 786E. ALT 最小割+倍增
E. ALT http://codeforces.com/problemset/problem/786/E 题意: 给出一棵 n 个节点的树与 m 个工人.每个工人有一条上下班路线(简单路径),一个工 ...
- Codeforces 628F 最大流转最小割
感觉和昨天写了的题一模一样... 这种题也能用hall定理取check, 感觉更最小割差不多. #include<bits/stdc++.h> #define LL long long # ...
- Codeforces 1009G Allowed Letters 最大流转最小割 sosdp
Allowed Letters 最直观的想法是贪心取, 然后网络流取check可不可行, 然后T了. 想到最大流可以等于最小割, 那么我们状压枚举字符代表的6个点连向汇点是否断掉, 然后再枚举64个本 ...
- Yet Another Maxflow Problem CodeForces - 903G (最小割,线段树)
大意: 两个n元素集合$A$, $B$, $A_i$与$A_{i+1}$连一条有向边, $B_i$与$B_{i+1}$连一条有向边, 给定$m$条从$A_i$连向$B_j$的有向边, 每次询问修改$A ...
- CodeForces E. Goods transportation【最大流+dp最小割】
妙啊 首先暴力建图跑最大流非常简单,s向每个i连流量为p[i]的边,每个i向t连流量为s[i]的边,每个i向j连流量为c的边(i<j),但是会又T又M 考虑最大流=最小割 然后dp求最小割,设f ...
- Codeforces 343E 最小割树
题意及思路:https://www.cnblogs.com/Yuzao/p/8494024.html 最小割树的实现参考了这篇博客:https://www.cnblogs.com/coder-Uran ...
- 最小割 D. Behind the Wall Samara University ACM ICPC 2016-2017 Quarterfinal Qualification Contest
题目链接:http://codeforces.com/gym/101149/problem/D 题目大意: 堡垒受到攻击.堡垒是n*m的矩阵,矩阵里刚开始都是平地,然后那个数值表示在当前平地上建一面墙 ...
随机推荐
- bigdata_ Kafka集群模式部署
环境:kafka 0.8.1.1 基本概念 Kafka维护按类区分的消息,称为主题(topic) 生产者(producer)向kafka的主题发布消息 消费者(consumer)向主题注册,并且接收发 ...
- Angular语法(二)——模板语法
双花括号{{}} <img src="{{heroImageUrl}}" style="height:30px"> <!-- "Th ...
- QuickReport的OnNeedData的触发情况
1.设置QuickReport的DataSet为空.2.在QuickReport的BeforePrint里面将要显示的数据集合初始化,如Query1.First;3.在OnNeedData里面写代码, ...
- 最简单的IdentityServer实现——项目基本结构与流程
项目结构 共分为三个组成部分: IdentityServer:用于登录.身份认证与授权 Api:提供获得授权后调用的各接口 Client(客户端,控制台):访问IdentityServer授权,再访问 ...
- 配置 Visual Studio Tools for Apache Cordova
原文:配置 Visual Studio Tools for Apache Cordova 1.连接地址 https://msdn.microsoft.com/zh-cn/library/vs/alm/ ...
- Codejock.Xtreme.Toolkit.Pro.v15.3.1 下载 与 VS2015补丁使用方法
Codejock.Xtreme.Toolkit.Pro.v15.3.1 下载 与 VS2015补丁使用方法 打算放在CSDN进行下载的,上传完成后发现资源分设置的1分,本打算赚点下载分的.在页面上没有 ...
- 什么是.NET Native?
使用CoreRT将.NET Core发布为Native应用程序 - KAnts - 博客园 http://www.cnblogs.com/ants/p/8630332.html Microsoft . ...
- [java代码库]-简易计算器(第二种)
[java代码库]-简易计算器(第二种) 第二种方案:在程序中不使用if/switch……case等语句,完成计算器功能. <html> <head> <title> ...
- 管道Demo
使用管道实现读取DOS命令结果,界面如下: 主要代码如下: UpdateData(TRUE); //创建一个管道,用于接收命令执行结果 SECURITY_ATTRIBUTES sa; ZeroMemo ...
- asp.net mvc+jquery easyui开发实战教程之网站后台管理系统开发1-准备工作
/****** Object: 新闻表 Script Date: 2017/9/2 星期六 15:11:12 ******/ SET ANSI_NULLS ON GO SET QUOTED_IDENT ...