把'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 ;
}

最新文章

  1. JAVE not work in linux
  2. UIProgressView改变高度
  3. Objective-C学习笔记类目、协议
  4. mysql维护常用命令
  5. IDEA建项目的正确姿势
  6. linux下如何安装rzsz
  7. webview改变网页宽度
  8. [转] Mac 下 PostgreSQL 的安装与使用
  9. nignx 测试配置文件
  10. Android之本地相冊图片选取和拍照以及图片剪辑
  11. js随机背景颜色
  12. Vue (三) --- Vue 组件开发
  13. 使用js获取页面参数
  14. .net 多线程之线程取消
  15. JAVA(五)反射机制/Annotation
  16. docker下centos安装ping命令
  17. ArcGIS API for Silverlight/ 开发入门 环境搭建
  18. css 2D转换总结
  19. Android性能优化工具之Systrace
  20. 运输层协议--TCP及UDP协议

热门文章

  1. Flutter实战视频-移动电商-02.Flutter实战建立项目和编写入口文件
  2. 线性SVM与Softmax分类器
  3. IT兄弟连 JavaWeb教程 JSP内置对象经典案例
  4. 百度搜索:有关Baiduspider的10个问题
  5. hibernate错误总结1
  6. STP-2-三个选择
  7. mongodb javaapi网页版链接
  8. PyAudio 实现录音 自动化交互实现问答
  9. POP页面暂时不销毁
  10. php—常见设计模式