博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Codeforces Gym 100203I I - I WIN 网络流最大流
阅读量:5366 次
发布时间:2019-06-15

本文共 3788 字,大约阅读时间需要 12 分钟。

I - I WIN

Time Limit: 20 Sec

Memory Limit: 256 MB

题目连接

http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87954#problem/I

Description

Given an n × m rectangular tile with each square marked with one of the letters 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 L-shaped ones, and the triominoes can't overlap.

Input

First line contains two integers n and m with 1 ≤ m, n ≤ 22. The next n lines contain m characters each (only the letters W, I and N).

Output

Output a single integer: the maximum number of nonoverlapping WIN-triominoes.

Sample Input

4 4

WIIW
NNNN
IINN
WWWI

Sample Output

5

HINT

 

题意

一个n*m的大矩形,问你最多切下多少只含有win的块数

题解

网络流,s-1-w-1-i-1-i-1-n-t,这样建图

注意w连i的时候,i也要再另外开一个点连,然后连n

不然两个w连同一个i,两个n连同一个i的时候,会出现问题

代码:

#include 
#include
#include
#include
using namespace std;namespace NetFlow{ const int MAXN=100000,MAXM=500000,inf=1e9; struct Edge { int v,c,f,nx; Edge() {} Edge(int v,int c,int f,int nx):v(v),c(c),f(f),nx(nx) {} } E[MAXM]; int G[MAXN],cur[MAXN],pre[MAXN],dis[MAXN],gap[MAXN],N,sz; void init(int _n) { N=_n,sz=0; memset(G,-1,sizeof(G[0])*N); } void link(int u,int v,int c) { E[sz]=Edge(v,c,0,G[u]); G[u]=sz++; E[sz]=Edge(u,0,0,G[v]); G[v]=sz++; } int ISAP(int S,int T) {
//S -> T int maxflow=0,aug=inf,flag=false,u,v; for (int i=0;i
E[it].f&&dis[u]==dis[v=E[it].v]+1) { if (aug>E[it].c-E[it].f) aug=E[it].c-E[it].f; pre[v]=u,u=v; flag=true; if (u==T) { for (maxflow+=aug;u!=S;) { E[cur[u=pre[u]]].f+=aug; E[cur[u]^1].f-=aug; } aug=inf; } break; } } if (flag) continue; int mx=N; for (int it=G[u];~it;it=E[it].nx) { if (E[it].c>E[it].f&&dis[E[it].v]
E[it].f) { dis[v]=dis[u]+1; Q[t++]=v; } } } return dis[T]!=-1; } int dfs(int u,int T,int low) { if (u==T) return low; int ret=0,tmp,v; for (int &it=cur[u];~it&&ret
E[it].f) { if (tmp=dfs(v,T,min(low-ret,E[it].c-E[it].f))) { ret+=tmp; E[it].f+=tmp; E[it^1].f-=tmp; } } } if (!ret) dis[u]=-1; return ret; } int dinic(int S,int T) { int maxflow=0,tmp; while (bfs(S,T)) { memcpy(cur,G,sizeof(G[0])*N); while (tmp=dfs(S,T,inf)) maxflow+=tmp; } return maxflow; }}using namespace NetFlow;char s[40][40];int dx[4]={ 1,-1,0,0};int dy[4]={ 0,0,1,-1};int nn,mm;int judge(int x,int y){ if(x<=0||x>nn) return 0; if(y<=0||y>mm) return 0; return 1;}int main(){ //freopen("test.txt","r",stdin); scanf("%d%d",&nn,&mm); init(15000); for(int i=1;i<=nn;i++) scanf("%s",s[i]+1); for(int i=1;i<=nn;i++) { for(int j=1;j<=mm;j++) { if(s[i][j]=='I') { link(i+j*30,i+j*30+1000,1); } } } for(int i=1;i<=nn;i++) { for(int j=1;j<=mm;j++) { if(s[i][j]=='W') { link(4000,i+j*30,1); for(int k=0;k<4;k++) { if(judge(i+dx[k],j+dy[k])) { if(s[i+dx[k]][j+dy[k]]=='I') { int ii=i+dx[k],jj=j+dy[k]; link(i+j*30,ii+jj*30,1); } } } } if(s[i][j]=='I') { for(int k=0;k<4;k++) { if(judge(i+dx[k],j+dy[k])) { if(s[i+dx[k]][j+dy[k]]=='N') { int ii=i+dx[k],jj=j+dy[k]; link(i+j*30+1000,ii+jj*30,1); } } } } if(s[i][j]=='N') { link(i+j*30,4001,1); } } } printf("%d\n",dinic(4000,4001)); return 0;}

 

转载于:https://www.cnblogs.com/qscqesze/p/4733312.html

你可能感兴趣的文章
WaitHandle.WaitAll 方法在WPF工程中的应用
查看>>
C#操作office进行Excel图表创建,保存本地,word获取
查看>>
程序员的自我修养——操作系统篇(转)
查看>>
vue-cli搭建项目
查看>>
开发一个支持多用户在线的FTP程序
查看>>
Linux下tail命令的使用方法
查看>>
jdk的安装和java的入门概念
查看>>
http://www.itpub.net/thread-1778530-1-1.html
查看>>
[转]Linux下的Makefile
查看>>
oracle执行代码段以及表分区
查看>>
[LeetCode] Remove Element
查看>>
c++ STL总结一:vertor和list
查看>>
python下载代码
查看>>
递归函数
查看>>
简直要逆天!超炫的 HTML5 粒子效果进度条
查看>>
分享5种风格的 jQuery 分页效果【附代码】
查看>>
TCP系列20—重传—10、早期重传(ER)
查看>>
IOS-TextField控件详解
查看>>
[置顶] ios App 中嵌入应用商店
查看>>
java多线程编程——同步器Exchanger
查看>>