Tile Cut~网络流入门题
Description
When Frodo, Sam, Merry, and Pippin are at the Green Dragon Inn drinking ale, they like to play a little game with parchment and pen to decide who buys the next round. The game works as follows: Given an m × n rectangular tile with each square marked with one of the incantations W, I, and N, find the maximal number of triominoes that can be cut from this tile such that the triomino has W and N on the ends and I in the middle (that is, it spells WIN in some order). Of course the only possible triominoes are the one with three squares in a straight line and the two ell-shaped ones. The Hobbit that is able to find the maximum number wins and chooses who buys the next round. Your job is to find the maximal number. Side note: Sam and Pippin tend to buy the most rounds of ale when they play this game, so they are lobbying to change the game to Rock, Parchment, Sword (RPS)!
Input
Each input file will contain multiple test cases. Each test case consists of an m × n rectangular grid (where 1 ≤ m, n ≤ 30) containing only the letters W, I, and N. Test cases will be separated by a blank line. Input will be terminated by end-of-file.
Output
For each input test case, print a line containing a single integer indicating the maximum total number of tiles that can be formed.
Sample Input
WIIW
NNNN
IINN
WWWI NINWN
INIWI
WWWIW
NNNNN
IWINN
Sample Output
5
5 以前一直不会网络流,直到现在遇到了网络流的题目才决定学一学。
这题就相当与我的网络流入门题吧。
这题其实是一个非常容易的网络流题目,只是我以前都不会。
所以觉得难,多看一些网络流的题目,多了解一些套路就可以了。
这里我用的是我的dinic模板。
现在自己仔细讲讲这题如何做,
题意:给你一张图,求出有几个WIN 。
网络流的难点就在构图上面,比较各种网络流模板差不多,都是当做
黑箱使用,如何构图就是一个艺术性的事情了。
其实这题类似于飞行员匹配问题,只是由两点匹配变成了三点匹配。
其实就是想办法转化为两点匹配,就是类似于二分图。
W是头,N是尾,所以主要处理的就是I,
主要说明一下构图原理,建立一个源点连接到所有的W,然后一个终点连接所有的N
这里最巧妙的就是in和out,
源点和out 【n*m,2*n*m-1】相连
终点和in 【0,n*m-1】 相连
所以这里处理I 就是将 I 作为连接 in 和 out 的桥梁
if (tu[i][j] == 'I') {
for (int k = 0 ; k < 4 ; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (tu[nx][ny] == 'W') f.add(nx * m + ny + out, i * n + j + in, 1) ;
if (tu[nx][ny] == 'N') f.add(i * m + j + out, nx * m + ny + in, 1) ;
}
}
这个就是核心代码了。
想必讲到这里 ,已经是非常非常详细了。
上代码
#include <vector>
#include <stdio.h>
#include <string>
#include <cstring>
#include <queue>
#include <iostream>
using namespace std;
const int maxn = 1e4 + ;
const int INF = 1e9 + ;
struct node {
int from, to, cap, flow;
};
struct Dinic {
int n, m, s, t;
vector<node>nodes;
vector<int>g[maxn];
int vis[maxn];
int d[maxn];
int cur[maxn];
void clearall(int n) {
for (int i = ; i < n ; i++) g[i].clear();
nodes.clear();
}
void clearflow() {
int len = nodes.size();
for (int i = ; i < len ; i++) nodes[i].flow = ;
}
void add(int from, int to, int cap) {
nodes.push_back((node) {
from, to, cap,
});
nodes.push_back((node) {
to, from, ,
});
m = nodes.size();
g[from].push_back(m - );
g[to].push_back(m - );
}
bool bfs() {
memset(vis, , sizeof(vis));
queue<int>q;
q.push(s);
d[s] = ;
vis[s] = ;
while(!q.empty()) {
int x = q.front();
q.pop();
int len = g[x].size();
for (int i = ; i < len ; i++) {
node &e = nodes[g[x][i]];
if (!vis[e.to] && e.cap > e.flow ) {
vis[e.to] = ;
d[e.to] = d[x] + ;
q.push(e.to);
}
}
}
return vis[t];
}
int dfs(int x, int a) {
if (x == t || a == ) return a;
int flow = , f, len = g[x].size();
for (int &i = cur[x] ; i < len ; i++) {
node & e = nodes[g[x][i]];
if (d[x] + == d[e.to] && (f = dfs(e.to, min(a, e.cap - e.flow))) > ) {
e.flow += f;
nodes[g[x][i] ^ ].flow -= f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
}
int maxflow(int a, int b) {
s = a;
t = b;
int flow = ;
while(bfs()) {
memset(cur, , sizeof(cur));
flow += dfs(s, INF);
}
return flow;
}
vector<int>mincut() {
vector<int>ans;
int len = nodes.size();
for (int i = ; i < len ; i++) {
node & e = nodes[i];
if ( vis[e.from] && !vis[e.to] && e.cap > ) ans.push_back(i);
}
return ans;
}
void reduce() {
int len = nodes.size();
for (int i = ; i < len ; i++) nodes[i].cap -= nodes[i].flow;
}
} f;
int ans(vector<string> &tu ) {
int n = tu.size(), m = tu[].length();
int source = * n * m, sink = * n * m + ;
int in = , out = n * m;
int dx[] = {, , , -};
int dy[] = {, , -, };
f.clearall( * n * m + );
f.clearflow();
for (int i = ; i < n ; i++) {
for (int j = ; j < m ; j++) {
f.add(i * m + j + in, i * m + j + out, );
if (tu[i][j] == 'W') f.add(source, i * m + j + in, );
if (tu[i][j] == 'I') {
for (int k = ; k < ; k++) {
int nx = i + dx[k];
int ny = j + dy[k];
if (nx < || nx >= n || ny < || ny >= m) continue;
if (tu[nx][ny] == 'W') f.add(nx * m + ny + out, i * m + j + in, ) ;
if (tu[nx][ny] == 'N') f.add(i * m + j + out, nx * m + ny + in, ) ;
}
}
if (tu[i][j] == 'N') f.add(i * m + j + out, sink, );
}
}
return f.maxflow(source, sink);
}
int main() {
while() {
string s;
vector<string> tu;
while(getline(cin, s)) {
if (s.length() == ) break;
tu.push_back(s);
}
if (tu.size() == ) break;
printf("%d\n", ans(tu));
}
return ;
}
Tile Cut~网络流入门题的更多相关文章
- poj1273 网络流入门题 dinic算法解决,可作模板使用
Drainage Ditches Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 62078 Accepted: 2384 ...
- POJ-1273Drainage Ditches(网络流入门题,最大流)
Every time it rains on Farmer John's fields, a pond forms over Bessie's favorite clover patch. This ...
- bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门
link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...
- 网络流最经典的入门题 各种网络流算法都能AC。 poj 1273 Drainage Ditches
Drainage Ditches 题目抽象:给你m条边u,v,c. n个定点,源点1,汇点n.求最大流. 最好的入门题,各种算法都可以拿来练习 (1): 一般增广路算法 ford() #in ...
- hdu 1312:Red and Black(DFS搜索,入门题)
Red and Black Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- 网络流入门-POJ1459PowerNetwork-Dinic模板
(我有什么错误或者你有什么意见,欢迎留言或私聊!谢谢!) (Ps:以前听说过网络流,想着以后再学,这次中南多校赛也碰到有关网络流的题目,想着这两天试着学学这个吧~~ 这是本人网络流入门第二题,不知道怎 ...
- Cogs 732. [网络流24题] 试题库(二分图)
[网络流24题] 试题库 ★★ 输入文件:testlib.in 输出文件:testlib.out 评测插件 时间限制:1 s 内存限制:128 MB «问题描述: 假设一个试题库中有n道试题.每道试题 ...
- Cogs 739. [网络流24题] 运输问题(费用流)
[网络流24题] 运输问题 ★★ 输入文件:tran.in 输出文件:tran.out 简单对比 时间限制:1 s 内存限制:128 MB «问题描述: «编程任务: 对于给定的m 个仓库和n 个零售 ...
- Cogs 727. [网络流24题] 太空飞行计划(最大权闭合子图)
[网络流24题] 太空飞行计划 ★★☆ 输入文件:shuttle.in 输出文件:shuttle.out 简单对比 时间限制:1 s 内存限制:128 MB [问题描述] W 教授正在为国家航天中心计 ...
随机推荐
- Python3 函数参数
# # 常规参数 # def jiafa(a,b): # print(a+b) # # jiafa(5,6) # # # def xinxi(name,location,sex='male'): # ...
- 【Consul】Consul架构-Session会话
Consul提供session会话机制--可以用于构建分布式锁,session可以绑定到节点.健康检查.KV数据.目的是提供颗粒锁--受 The Chubby LockService for Loos ...
- .NET中调用不安全代码
.NET中是不允许不安全的代码的,比如指针等.但有些特殊场合还是需要用到指针,这时候就需要在你的代码块上加上unsafe标签.如: 1: unsafe static void Main( ...
- 在Linux下通过rpm打包发布Java程序
这个东西涉及的内容较多,根据下面这些文章慢慢学习 一个简单的例子 http://blog.csdn.net/king_on/article/details/7169384 按照文章中的步骤来,打包之后 ...
- 一个知乎日报pwa
前几天写了一篇文章关于如何实现一个简单版的pwa应用,端午撸了一个简易版知乎日报pwa. 关于如何写一个pwa,这里就不多介绍了,请移步这里.应用使用vue+vuex+axios,API这里,这里做了 ...
- 常用模块(数据序列化 json、pickle、shelve)
本节内容 前言 json模块 pickle模块 shelve模块 总结 一.前言 1. 现实需求 每种编程语言都有各自的数据类型,其中面向对象的编程语言还允许开发者自定义数据类型(如:自定义类),Py ...
- jmeter实例,如果有说明错误,请各位大神批评
首先我们打开jmeter,今天录制的脚本的是获取QQ头像,找了好久才找到可以免费试用的接口,如果有什么错误的地方,欢迎大家提出来,我会及时修改,也给自己一次进步的机会,希望大家不吝赐教!!!如果有什么 ...
- ThinkPHP自定义成功界面、失败界面、异常界面
在ThinkPHP的手册中,附录里边的配置参考,有一个模板引擎设置. 或者在手册里面的控制器,跳转和重定向里面. 紧接着,就讲到了如何自定义这些界面. 将上诉的配置参数写到到配置文件里,修改路径到自己 ...
- picker组件,mode=date,苹果机年份从1开始
由于在IOS上复制图片不方便, 所以用了张别的网站的图 这是在没有设置value和start的情况下出现的,安卓机上显示是好的.尝试完网上相关说法, 发现都不中! 通过各种挣扎啊!~ 心里苦啊~ 复制 ...
- Luogu2570 ZJOI2010 贪吃的老鼠 二分答案+最大流
题目链接:https://www.luogu.org/problemnew/show/P2570 题意概述: 好像没什么好概述的.....很简洁? 分析: 首先想到二分时间,转化成判定性问题,在一定时 ...