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] 软件开发(最小费用最大流)
不知道为什么这么慢.... 费用流,拆点.... --------------------------------------------------------------------------- ...
随机推荐
- 模型层TP框架数据库的操作
在shop入口的文件下的HOME文件夹中使用模型层 第一步修改配置模块把数据库的各种链接做好,打开HOME中的conf文件夹中的config.php,找到Thinkphp文件加下的conf文件打开co ...
- 九度OJ 1180:对称矩阵 (矩阵计算)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:2637 解决:1354 题目描述: 输入一个N维矩阵,判断是否对称. 输入: 输入第一行包括一个数:N(1<=N<=100),表 ...
- SVM vs. Softmax
http://cs231n.github.io/linear-classify/
- python基础-第五篇-5.2递归
又是一个阳光明媚的日子,小白看着刚刚从东边升起的太阳,感觉太阳爷爷也在向她打招呼,小白就不经的微笑起来!心想:今天又会学到什么有趣的东西呢?有些小期待,也有些小激动! 小刘来得比小白还早,两辆相视而笑 ...
- CENTOS7 修改网卡名称为eth[012...],格式
具体操作是修改/etc/default/grub文件 在GRUB_CMDLINE_LINUX一行中添加net.ifnames=0 biosdevname=0 保存文件后然后运行 grub2-mkcon ...
- 只需两步删除 node_modules
peng@PENG-PC /E/_My_File_____/home/learn/web_qianduan/mithril-demo/demo2/mithril -demo $ npm install ...
- js完美实现table分页
// JavaScript Document /** * js分页类 * @param iAbsolute 每页显示记录数 * @param sTableId 分页表格属性ID值,为String * ...
- spring AOP简单实现代码存放
@Before:使用Before增强处理只能在目标方法执行之前织入增强,如果Before增强处理没有特殊处理,目标方法总会自动执行,如果Before处需要阻止目标方法的执行,可通过抛出一个异常来实现. ...
- python操作mysql(一)原生模块pymysql
一.下载安装 pymsql是Python中操作MySQL的模块,其使用方法和MySQLdb几乎相同. 下载安装 C:\Users\Administrator>pip install pymysq ...
- Eclipse快捷键与Notepad++ 快捷建冲突的问题
notepad++添加了zen coding插件以后,notepad++默认的快捷键中Alt+/也是其快捷键中的一个,表示toggle comment,而用myeclipce或eclipse的朋友都知 ...