bzoj 3171: [Tjoi2013]循环格 最小费用最大流
题目大意:
题解:
首先我们很容易发现一个结论:
出现完美循环当且仅当所有点的出入度均为1
所以利用这个性质,我们将每个点拆成两个点
S连向出点,入点连向T,然后出点向上下左右的入点连边
跑最小费用最大流即可.
#include <cstdio>
#include <cstring>
#include <cassert>
#include <algorithm>
using namespace std;
typedef long long ll;
inline void read(int &x){
x=0;char ch;bool flag = false;
while(ch=getchar(),ch<'!');if(ch == '-') ch=getchar(),flag = true;
while(x=10*x+ch-'0',ch=getchar(),ch>'!');if(flag) x=-x;
}
inline int cat_max(const int &a,const int &b){return a>b ? a:b;}
inline int cat_min(const int &a,const int &b){return a<b ? a:b;}
const int maxnode = 512;
const int maxedge = 4096;
struct Edge{
int to,next,cap,cost;
}G[maxedge<<1];
int head[maxnode],cnt=1;
void add(int u,int v,int c,int d){
G[++cnt].to = v;
G[cnt].next = head[u];
head[u] = cnt;
G[cnt].cap = c;
G[cnt].cost = d;
}
inline void insert(int u,int v,int c,int d){
add(u,v,c,d);add(v,u,0,-d);
}
#define v G[i].to
const int lim = maxnode<<1;
int dis[maxnode],p[maxnode],q[lim + 10],flow[maxnode];
int l,r,S,T,ans;bool inq[maxnode];
const int inf = 0x3f3f3f3f;
bool spfa(){
memset(dis,0x3f,sizeof dis);
dis[S] = 0;flow[S] = inf;
inq[S] = true;l = 0;r = -1;
q[++r] = S;
while(l <= r){
int u = q[l % lim];++l;
for(int i = head[u];i;i=G[i].next){
if(dis[v] > dis[u] + G[i].cost && G[i].cap){
dis[v] = dis[u] + G[i].cost;
flow[v] = min(flow[u],G[i].cap);
p[v] = i;
if(!inq[v]){
q[++r % lim] = v;
inq[v] = true;
}
}
}inq[u] = false;
}if(dis[T] == dis[0]) return false;
ans += dis[T]*flow[T];
for(int u = T;u != S;u = G[p[u]^1].to){
G[p[u]].cap -= flow[T],G[p[u]^1].cap += flow[T];
}
return true;
}
#undef v
#define f(x,y) ((x-1)*m + y)
int dx[] = {0,0,1,-1};
int dy[] = {1,-1,0,0};
inline int id(const char &ch){
if(ch == 'U') return 3;
if(ch == 'D') return 2;
if(ch == 'L') return 1;
if(ch == 'R') return 0;
return -1;
}
int main(){
int n,m;read(n);read(m);
S = maxnode - 5;T = S+1;
char ch;
for(int i=1,x;i<=n;++i){
for(int j=1;j<=m;++j){
insert(f(i,j)<<1,T,1,0);
insert(S,f(i,j)<<1|1,1,0);
while(ch=getchar(),ch<'!');
x = id(ch);if(x == -1) assert(0);
for(int k=0;k<4;++k){
int nx = i + dx[k];if(nx == n+1) nx = 1;if(nx == 0) nx = n;
int ny = j + dy[k];if(ny == m+1) ny = 1;if(ny == 0) ny = m;
insert(f(i,j)<<1|1,f(nx,ny)<<1,1,x != k);
}
}
}
while(spfa());
printf("%d\n",ans);
getchar();getchar();
return 0;
}
bzoj 3171: [Tjoi2013]循环格 最小费用最大流的更多相关文章
- BZOJ 3171 [Tjoi2013]循环格(费用流)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题目大意] 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子. 每 ...
- Bzoj 3171: [Tjoi2013]循环格 费用流
3171: [Tjoi2013]循环格 Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 741 Solved: 463[Submit][Status][ ...
- bzoj 3171 [Tjoi2013]循环格(MCMF)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=3171 [题意] 给定一个方向矩阵,要求改变最少的格子,使得任意一个点都在一个环中. [ ...
- bzoj 3171: [Tjoi2013]循环格
#include<cstdio> #include<iostream> #include<cstring> #define M 10000 #define inf ...
- 3171. [TJOI2013]循环格【费用流】
Description 一个循环格就是一个矩阵,其中所有元素为箭头,指向相邻四个格子.每个元素有一个坐标(行,列),其中左上角元素坐标为(0,0).给定一个起始位置(r,c) ,你可以沿着箭头防线在格 ...
- BZOJ 2668 [cqoi2012]交换棋子 | 最小费用最大流
传送门 BZOJ 2668 题解 同时分别限制流入和流出次数,所以把一个点拆成三个:入点in(x).中间点mi(x).出点ou(x). 如果一个格子x在初始状态是黑点,则连(S, mi(x), 1, ...
- BZOJ 1061 志愿者招募(最小费用最大流)
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1061 题意:申奥成功后,布布经过不懈努力,终于 成为奥组委下属公司人力资源部门的主管.布 ...
- bzoj 1070 [SCOI2007]修车(最小费用最大流)
1070: [SCOI2007]修车 Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 3515 Solved: 1411[Submit][Status] ...
- BZOJ 1221: [HNOI2001] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
随机推荐
- java jdbc连接数据库,Properties 属性设置参数方法
今天在整合为数据库发现在配置中实现的赋值方式,可以用代码实现.特记录下共以后参考: 代码: // 操作数据库 Connection conn; String strData ...
- 大数进制转换 poj1220
普通的做法,大数除小数. 复杂度o( log(n)*log(n) ),其实就是位数的平方. NUMBER BASE CONVERSION Time Limit: 1000MS Memory Lim ...
- 九度OJ 1334:占座位 (模拟)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:864 解决:202 题目描述: sun所在学校的教室座位每天都是可以预占的. 一个人可以去占多个座位,而且一定是要连续的座位,如果占不到他所 ...
- CentOS7.1安装 Vsftpd FTP 服务器
# yum install vsftpd 安装 Vsftpd FTP 编辑配置文件 ‘/etc/vsftpd/vsftpd.conf’ 用于保护 vsftpd. # vi /etc/vsftpd/vs ...
- html/css背景图片自适应分辨率大小
<style type='text/css'> .bgbox { position: absolute; left: 0; top: 0; width: 100%; overflow: h ...
- zabbix 主机组管理
分组的目的是将同一属性的主机归类,主机组中可以包含主机,也可以包含模板 建议:同一属性的主机或者模板,尽量归纳到分组中方便以后管理.分组原则如下: 以地理位置进行划分 以业务划分 以机器用途划分 以系 ...
- 3.07课·········if分支语句
语句分类:顺序语句,选择语句(分支语句),循环语句 分支语句:(一)if(表达式) //表达式返回值是True或False{}说明:1.表达式返回的是bool值:2.小括号和花括号后面不需要加分号. ...
- [原创]java WEB学习笔记02:javaWeb开发的目录结构
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- P1393 动态逆序对
题目 P1393 动态逆序对 做题前写篇博客是个好方法 做法 题目规定仅有删除,给每个位置标个号,逆序对+时间轴,显然这是个三维偏序 很久没做过\(cdq\)了,就当模板题讲一下: 按删除的先后顺序为 ...
- delphi的获取某坐标的颜色值
1.通过API函数GetPixel(),获取某个点的颜色值; var PT : TPoint; C : TColor; DC : HDC; hwd : THandle; I : integer; be ...