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的矩阵,矩阵里刚开始都是平地,然后那个数值表示在当前平地上建一面墙 ...
随机推荐
- Feature extraction - sklearn文本特征提取
http://blog.csdn.net/pipisorry/article/details/41957763 文本特征提取 词袋(Bag of Words)表征 文本分析是机器学习算法的主要应用领域 ...
- WPF 代码实现动画
<Window x:Class="wpf180709.Window2" xmlns="http://schemas.microsoft.com/win ...
- Win10《芒果TV》跨年邀你嗨唱,同步直播《湖南卫视2017-2018跨年演唱会》
由天天兄弟.快本家族联袂主持,不容错过的年度盛典<湖南卫视2017-2018跨年演唱会>将于2017年12月31日19:30起由芒果TV同步直播,果妈备上礼物邀您一起跨年嗨唱. 跨年邀你嗨 ...
- 零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」
原文:零元学Expression Blend 4 - Chapter 8 用实例了解布局容器系列-「Grid」 本系列将教大家以实做案例认识Blend 4 的布局容器,此章介绍的是Blend 4 里的 ...
- UWP入门(七)--SplitView详解与页面跳转
原文:UWP入门(七)--SplitView详解与页面跳转 官方文档,逼着自己用英文看,UWP开发离不开官方文档 1. SplitView 拆分视图控件 拆分视图控件具有一个可展开/可折叠的窗格和一个 ...
- 建立Linux计划命令crontab
crontab翻译:排程,命令 crontab从输入设备输入命令,并将其放入crontab文件,供守护进程crond读取并执行,crond在后台每一分钟执行一次 crontab -e:创建计划命令,进 ...
- 腾讯网移动端H5页面设计实战分享
分享 <关于我> 分享 [中文纪录片]互联网时代 http://pan.baidu.com/s/1qWkJfcS 分享 <HTML开发MacOSAp ...
- 开源玩家福利:十大Linux免费游戏
假如当你考虑从Windows平台迁移至Linux平台时,“我能在Linux平台上游戏吗?”这类疑问正困扰着你,那么对此这有一个答案就是“快去Linux平台吧!”.感谢开源组织一直以来坚持不懈为Linu ...
- 条款17:以独立语句将newed对象置入智能指针
请牢记: 以独立语句将newed对象存储于(置入)智能指针内.如果不这样做,一旦异常被跑出来,有可能导致难以察觉的资源泄露. 假设有个函数用来处理程序的优先权,另一个函数用来在某动态分配所得的Widg ...
- Arcgis Server 10.4.1 搭建集群环境
1.准备工作 Arcgis Server 10.4.1 以及许可一枚 共享存储(通过UNC路径访问,如"\\server1\arcgisserver\") 服务器两台(虚拟机也可 ...