把'I'拆成容量为1一条边,一个入点一个出点,入点和相邻的'W'连一条容量为1的边,出点和相邻的'N'连一条容量为1,所有的'W'和源点连一条容量为1边,所有的'N'和汇点连一条容量为1的边,表示只能用一次。一发网络流就过了。

写了4000B+的贪心,然并卵

#include<bits/stdc++.h>
using namespace std; const int INF = 0x3fffffff;
const int maxn = ;
#define PB push_back
struct Edge
{
int from,to,cap,flow;
}; vector<Edge> edges;
vector<int> G[maxn];
int S ,T ; void AddEdge(int from,int to,int cap)
{
edges.PB(Edge{from,to,cap,});
edges.PB(Edge{to,from,,});
int m = edges.size();
G[from].PB(m-);
G[to].PB(m-);
} bool vis[maxn];
int d[maxn],cur[maxn]; bool bfs()
{
memset(vis,,sizeof(vis));
queue<int> q;
q.push(S);
d[S] = ;
vis[S] = true;
while(q.size()){
int u = q.front(); q.pop();
for(int i = ; i < G[u].size(); i++){
Edge &e = edges[G[u][i]];
if(!vis[e.to] && e.cap > e.flow){
vis[e.to] = true;
d[e.to] = d[u] + ;
q.push(e.to);
}
}
}
return vis[T];
} int dfs(int u,int a)
{
if(u == T || a == ) return a;
int flow = , f;
for(int &i = cur[u]; i < G[u].size(); i++){
Edge &e = edges[G[u][i]];
if(d[u] + == d[e.to] && (f = dfs(e.to,min(a,e.cap-e.flow))) >){
e.flow += f;
edges[G[u][i]^].flow -= f;
flow += f;
a -= f;
if(a == ) break;
}
}
return flow;
} int MaxFlow()
{
int flow = ;
while(bfs()){
memset(cur,,sizeof(cur));
flow += dfs(S,INF);
}
return flow;
} typedef pair<int,int> pii;
#define fi first
#define se second
#define MP make_pair
vector<pii> vec; const int N = ;
char s[N][N];
int id[N][N]; int dx[] = {,,-,};
int dy[] = {,-,,}; int main()
{
//freopen("in.txt","r",stdin);
int n,m; scanf("%d%d",&n,&m);
int Icnt = , Wcnt = , Ncnt = ;
for(int i = ; i <= n; i++){
scanf("%s",s[i]+);
for(int j = ; j <= m; j++){
if(s[i][j] == 'I'){
vec.PB(MP(i,j));
id[i][j] = Icnt++;
}
if(s[i][j] == 'W'){
id[i][j] = Wcnt++;
}
if(s[i][j] == 'N'){
id[i][j] = Ncnt++;
}
}
}
int MW = Icnt* + ;
int MN = MW + Wcnt + ;
S = MN +Ncnt + ; T = MN +Ncnt + ;
for(int i = ; i < vec.size(); i++){
int x = vec[i].fi, y = vec[i].se;
int in = *i+, out = *i+;
AddEdge(in,out,);
for(int k = ; k < ; k++){
int nx = x+dx[k], ny = y+dy[k];
if(s[nx][ny] == 'W'){
int u = id[nx][ny]+MW;
AddEdge(u,in,);
}
if(s[nx][ny] == 'N'){
int v = id[nx][ny]+MN;
AddEdge(out,v,);
}
}
}
for(int i = ; i <= n; i++)
for(int j = ; j <= m; j++){
if(s[i][j] == 'W'){
int v = id[i][j]+MW;
AddEdge(S,v,);
}
if(s[i][j] == 'N'){
int u = id[i][j]+MN;
AddEdge(u,T,);
}
}
int ans = MaxFlow();
printf("%d",ans);
return ;
}

codeforce Gym 100203I I WIN (网络流)的更多相关文章

  1. Gym - 100203I I WIN 网络流

    Gym - 100203I  I WIN 题意:一个n*m的矩阵包含W,I,N三种字符,问相邻的字符最多能组成不重叠的WIN. 思路:比赛的时候没有发现是网络流,,居然一度以为是二分图匹配,,写了一下 ...

  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. Codeforce Gym 100015I Identity Checker 暴力

    Identity Checker 题目连接: http://codeforces.com/gym/100015/attachments Description You likely have seen ...

  5. codeforce gym/100495/problem/K—Wolf and sheep 两圆求相交面积 与 gym/100495/problem/E—Simple sequence思路简述

    之前几乎没写过什么这种几何的计算题.在众多大佬的博客下终于记起来了当时的公式.嘚赶快补计算几何和概率论的坑了... 这题的要求,在对两圆相交的板子略做修改后,很容易实现.这里直接给出代码.重点的部分有 ...

  6. codeforce Gym 101102A Coins (01背包变形)

    01背包变形,注意dp过程的时候就需要取膜,否则会出错. 代码如下: #include<iostream> #include<cstdio> #include<cstri ...

  7. codeforce gym/100495/problem/F Snake++——DFS应用

    emmmm.... 在被新生暴打后,我花了很久才补出这道DFS.由于WA1检查了半天,最后竟然是输出少了一个:   ,心态小崩. 这里普通的dfs算出的连通区域并不能直接当做最后的答案.所以需要类似模 ...

  8. codeforce Gym 100425E The Street Escalator(期望,线性递推)

    算数学期望,每个人都可以分开来考虑.Xi表示第i个人跑到另外一边的次数. Xi服从二项分布.概率的和是个二项式,(p+1-p)^T,把二项式展开,p的偶次项是留在原来那一边的概率. 可以用((a+b) ...

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

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

随机推荐

  1. 安装openstack出现的问题及解决

    感谢http://www.cnblogs.com/nmap/p/6417163.html,参考这篇文章,我在虚拟机上部署成功了,后来因为虚拟机实在带不动,所以改装到物理机上,在实验室找到两台物理机,分 ...

  2. 【Linux学习】Linux系统管理2—作业调度

    Linux系统管理2-作业调度 at: 作业仅执行一次就从系统工作队列中取消 语法 denny@ubuntu:~$ at [-m] TIME                     → 作业命令at ...

  3. 在junit格式的结果信息中只包含错误信息的修改方法

    文件名称:suiteJunit.vm 文件路径:src\fitnesse\resources\templates 添加如下黑体部分内容: <?xml version="1.0" ...

  4. HDU2852【树状数组+二分】

    额..有点遗忘了树状数组特性了..印象中一直是前缀和,然后一定要记住树状数组是把给出的值(值太大可能可以离散化)也就是点到了区间,然后这个点存的值就是由自己来定了. 题意: 百度. 思路: 树状数组是 ...

  5. UGUI DOTween渐隐渐现

    Tween tweenAlpha; tweenAlpha = DOTween.To(() => MaskSpr.fillAmount, x => MaskSpr.fillAmount = ...

  6. Codevs 1976 Queen数列

    1976 Queen数列  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 黄金 Gold 题解       题目描述 Description 将1到N的整数数列(1,2,3,… ...

  7. 用生产者消费模型爬取智联招聘python岗位信息

    爬取python岗位智联招聘 这里爬取北京地区岗位招聘python岗位,并存入EXECEL文件内,代码如下: import json import xlwt import requests from ...

  8. morphia(5)-删除

    @Test public void delete() throws Exception { final Query<Employee> query = datastore.createQu ...

  9. 108 Convert Sorted Array to Binary Search Tree 将有序数组转换为二叉搜索树

    将一个按照升序排列的有序数组,转换为一棵高度平衡二叉搜索树.此题中,一个高度平衡二叉树是指一个二叉树每个节点的左右两个子树的高度差的绝对值不超过1.示例:给定有序数组: [-10,-3,0,5,9], ...

  10. Retrofit实现Delete请求

    //设置取消关注 @Headers("Content-Type:application/x-www-form-urlencoded") @HTTP(method = "D ...