Gym - 100203I  I WIN

题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN。

思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下没过就没改了,,知道了是网络流就好办了。设一个起点一个终点,起点和每个W之间连一条边,N和终点间连一条边,W和I之间连一条边,I和N之间连一条边,不过这里为了避免重复使用同一个I,应改成W到I连一条边,I连一条边到I',再从I'连一条边到N就可以保证最优解了。求一遍最大流即可。

 #include <iostream>
#include <cstdio>
#include <fstream>
#include <algorithm>
#include <cmath>
#include <deque>
#include <vector>
#include <queue>
#include <string>
#include <cstring>
#include <map>
#include <stack>
#include <set>
#define LL long long
#define eps 1e-8
#define INF 0x3f3f3f3f
#define MAXN 1005
using namespace std; struct Edge{
int from, to, cap, flow;
//Edge(int u, int v, int c, int f) :from(u), to(v), cap(c), flow(f){};
};
struct Dinic{
int n, m, i, s, t;
Edge e;
vector<Edge> edges;
vector<int> G[MAXN];
int d[MAXN], cur[MAXN];
bool vis[MAXN];
void init(int n){
this->n = n;
for (i = ; i <= n; i++){
G[i].clear();
}
edges.clear();
}
void AddEdge(int from, int to, int cap){
edges.push_back(Edge{ from, to, cap, });
edges.push_back(Edge{ to, from, , });
m = edges.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();
for (i = ; i < G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (!vis[e.to] && e.cap > e.flow){
vis[e.to] = true;
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;
for (int& i = cur[x]; i < G[x].size(); i++){
Edge& e = edges[G[x][i]];
if (d[x] + == d[e.to] && (f = DFS(e.to, min(a, e.cap - e.flow))) > ){
e.flow += f;
edges[G[x][i] ^ ].flow -= f;
flow += f;
a -= f;
if (a == ) break;
}
}
return flow;
}
int MaxFlow(int s, int t, int need){
int flow = ;
this->s = s;
this->t = t;
while (BFS()){
memset(cur, , sizeof(cur));
flow += DFS(s, INF);
if (flow > need) return flow;
}
return flow;
}
};
char a[][];
Dinic p;
const int step[][] = { , , , , -, , , - };
bool vis[][];
int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
#endif // OPEN_FILE
int n, m;
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++){
scanf("%s", a[i] + );
}
int s = , t = * n * m + ;
p.init(t);
memset(vis, , sizeof(vis));
for (int i = ; i <= n; i++){
for (int j = ; j <= m; j++){
int u = (i - ) * m + j;
if(a[i][j] == 'W'){
p.AddEdge(s, u, );
for (int k = ; k < ; k++){
int x = i + step[k][];
int y = j + step[k][];
if (x < || y < || x > n || y > m) continue;
if (a[x][y] == 'I'){
p.AddEdge(u, (x - ) * m + y, );
}
}
}
else if (a[i][j] == 'I'){
int v = u + n * m;
p.AddEdge(u, v, );
for (int k = ; k < ; k++){
int x = i + step[k][];
int y = j + step[k][];
if (x < || y < || x > n || y > m) continue;
if (a[x][y] == 'N'){
p.AddEdge(v, (x - ) * m + y, );
if (vis[x][y]) continue;
p.AddEdge((x - ) * m + y, t, );
vis[x][y] = true;
}
}
}
}
}
int ans = p.MaxFlow(s, t, INF);
printf("%d\n", ans);
}

Gym - 100203I I WIN 网络流的更多相关文章

  1. codeforce Gym 100203I I WIN (网络流)

    把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能 ...

  2. Codeforces Gym 100203I I WIN 最大流

    原题链接:http://codeforces.com/gym/100203/attachments/download/1702/statements.pdf 题解 首先寻找每个I,然后枚举形状,如果匹 ...

  3. Codeforces Gym 100203I I - I WIN 网络流最大流

    I - I WINTime Limit: 2 Sec Memory Limit: 256 MB 题目连接 http://acm.hust.edu.cn/vjudge/contest/view.acti ...

  4. Gym - 101128F Landscaping(网络流)

    题意 给你一个\(N×M\)的草地,有高地有低地. 收割机从低地走到高地或者从高地走到低地都要花费用\(A\),你可以花费用\(B\)把一块高地变成低地,或者把一块低地变成高地.收割机每行每列都是必须 ...

  5. Gym 101128F Landscaping(网络流)题解

    题意:n*m的地,从有高地和低地,从高地走到低地或者从低地走到高地花费a,把高地和低地互相改造一次花费b.现在要走遍每一行每一列,问最小花费 思路:超级源点连接所有低地,容量b:所有地向四周建边,容量 ...

  6. C - Portals Gym - 102006C (网络流最小割)

    题目链接:https://cn.vjudge.net/contest/283918#problem/C 题目大意:T个测试数据,然后给你一个字符串,每一个字符串包括‘s’,‘t’,‘o’,‘#’,‘. ...

  7. Gym 101128F Sheldon Numbers(网络流)

    [题目链接] http://codeforces.com/gym/101128/attachments [题目大意] 给出一张地图,分为高地和低地,高低地的交界线上划有红线, 现在要开小车跨过每条红线 ...

  8. codeforces gym 100357 J (网络流)

    题目大意 有n种物品,m种建筑,p个人. n,m,p∈[1,20] 每种建筑需要若干个若干种物品来建造.每个人打算建造一种建筑,拥有一些物品. 主角需要通过交易来建造自己的建筑,交易的前提是对方用多余 ...

  9. Landscaping Gym - 101128F (网络流)

    Problem F: Landscaping \[ Time Limit: 1 s \quad Memory Limit: 256 MiB \] 题意 题意是给出一个\(n*m\)的格子,其中一些是低 ...

随机推荐

  1. Rancher介绍安装以及对docker的管理

    原文:Rancher介绍安装以及对docker的管理 一.简介 Rancher是一个开源的企业级全栈化容器部署及管理平台.Rancher为容器提供一揽子基础架构服务:CNI兼容的网络服务.存储服务.主 ...

  2. 题解 P3200 【[HNOI2009]有趣的数列】

    说起来这是今天第三道卡特兰数了... 楼上的几篇题解好像都是直接看出这是卡特兰数,所以我就写一下为什么这道题可以用卡特兰数吧. 考察这样相邻的两项:\(a_{2i-1}\)与\(a_{2i}\),根据 ...

  3. MapReduce中combine、partition、shuffle的作用是什么

    http://www.aboutyun.com/thread-8927-1-1.html Mapreduce在hadoop中是一个比較难以的概念.以下须要用心看,然后自己就能总结出来了. 概括: co ...

  4. Linux在中国的没落

    6月23日,Linux kernel 4.1(LTS)公布.在国际自由软件世界引起热烈反响. 反观我们国内,官方机构没有不论什么动静:在民间,Linux激情已经消失.与十几年前相比.Linux在国内已 ...

  5. HDU 1039.Easier Done Than Said?【字符串处理】【8月24】

    Easier Done Than Said? Problem Description Password security is a tricky thing. Users prefer simple ...

  6. 【剑指Offer面试题】 九度OJ1516:调整数组顺序使奇数位于偶数前面

    题目链接地址: http://ac.jobdu.com/problem.php?pid=1516 题目1516:调整数组顺序使奇数位于偶数前面 时间限制:1 秒内存限制:128 兆特殊判题:否提交:2 ...

  7. 使用bbed恢复表数据

    对于表级别的数据恢复,ORACLE提供了多种恢复方法:flashback query,logmnr等. 本文通过演示样例演示使用bbed的copy命令恢复用户误删除或者损坏的表数据,当然我们也能够使用 ...

  8. SSL 延迟与 Http、Https

    SSL延迟有多大? 1. 基本概念 ssl 协议由网景公司(Netscape)设计,由此网络链接从 http 逐步走向更为安全的 https 加密链接模式. HTTPs 链接和 HTTP 链接都建立在 ...

  9. Autofac依赖注入框架

    最近使用Autofac框架做项目的依赖注入,感觉挺好用的. 没有深入研究,只是拿来用用,具体可以去官网看看:https://autofac.org/. 这里只是贴一下最近项目的配置: public p ...

  10. POJ 4007 Flood-it!

    题目:http://poj.org/problem?id=4007 思路: (lyd学长的思路) IDA*算法,首先迭代加深限制搜索深度. 可以发现如果当前矩阵中除了左上角的连通块之外,共有M种颜色, ...