I-i WIN
Time Limit:20 Sec
Memory limit:256 MB
Topic Connection
Http://acm.hust.edu.cn/vjudge/contest/view.action?cid=87954#problem/I
Description
Given an n x m rectangular tiles with each square marked with one of the letters W, I, and N, find th E maximal number of triominoes that can is cut from this tile such that the Triomino have W and N on the ends and I in the Middle (that's, it spells WIN in some order). Of course the only possible triominoes is the one with three squares in a straight line and the l-shaped ones, and the TR Iominoes can ' t overlap.
Input
First line contains-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
Test instructions
A n*m big rectangle, ask you to cut down how many of the number of blocks containing win
The following:
Network flow, S-1-W-1-I-1-I-1-N-T, so build a map
Note that W even I, I also want to open another point to connect, and then even n
Otherwise two w together with an I, two n with an I, there will be problems
Code:
#include <cstdio>#include<algorithm>#include<cstring>#include<iostream>using namespacestd;namespacenetflow{Const intmaxn=100000, maxm=500000, inf=1e9; structEdge {intV,c,f,nx; Edge () {} Edge (intVintCintFintNX): V (v), C (c), F (f), NX (NX) {}} E[MAXM]; intG[maxn],cur[maxn],pre[maxn],dis[maxn],gap[maxn],n,sz; voidInitint_n) {N=_n,sz=0; memset (g,-1,sizeof(g[0])*N); } voidLinkintUintVintc) {E[sz]=edge (V,c,0, G[u]); g[u]=sz++; E[SZ]=edge (U,0,0, G[v]); g[v]=sz++; } intISAP (intSintT) {//T-S intmaxflow=0, aug=inf,flag=false, U,v; for(intI=0; i<n;++i) cur[i]=g[i],gap[i]=dis[i]=0; for(gap[s]=n,u=pre[s]=s;dis[s]<n;flag=false) { for(int&it=cur[u];~it;it=e[it].nx) { if(e[it].c>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+=; E[cur[u]^1].f-=; } the=inf; } Break; } } if(flag)Continue; intmx=N; for(intit=g[u];~it;it=e[it].nx) { if(e[it].c>e[it].f&&dis[e[it].v]<mx) {mx=DIS[E[IT].V]; cur[u]=it; } } if((--gap[dis[u]) = =0) Break; ++gap[dis[u]=mx+1]; u=Pre[u]; } returnMaxflow; } BOOLBFsintSintT) {Static intQ[MAXN]; memset (dis,-1,sizeof(dis[0])*N); Dis[s]=0; q[0]=S; for(intH=0, t=1, u,v,it;h<t;++h) { for(u=q[h],it=g[u];~it;it=e[it].nx) { if(dis[v=e[it].v]==-1&&E[it].c>e[it].f) {Dis[v]=dis[u]+1; q[t++]=v; } } } returndis[t]!=-1; } intDfsintUintTintLow ) { if(u==t)returnLow ; intret=0, Tmp,v; for(int&it=cur[u];~it&&ret<low;it=e[it].nx) { if(dis[v=e[it].v]==dis[u]+1&&E[it].c>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;returnret; } intDinic (intSintT) {intmaxflow=0, TMP; while(BFS (s,t)) {memcpy (cur,g,sizeof(g[0])*N); while(Tmp=dfs (S,t,inf)) maxflow+=tmp; } returnMaxflow; }}using namespaceNetFlow;Chars[ +][ +];intdx[4]={1,-1,0,0};intdy[4]={0,0,1,-1};intnn,mm;intJudgeintXinty) { if(x<=0|| X>nn)return 0; if(y<=0|| Y>mm)return 0; return 1;}intMain () {//freopen ("Test.txt", "R", stdin);scanf"%d%d",&nn,&mm); Init (15000); for(intI=1; i<=nn;i++) scanf ("%s", s[i]+1); for(intI=1; i<=nn;i++) { for(intj=1; j<=mm;j++) { if(s[i][j]=='I') {Link (i+j* -, i+j* -+ +,1); } } } for(intI=1; i<=nn;i++) { for(intj=1; j<=mm;j++) { if(s[i][j]=='W') {Link (4000, i+j* -,1); for(intk=0;k<4; k++) { if(Judge (i+dx[k],j+Dy[k])) { if(s[i+dx[k]][j+dy[k]]=='I') { intii=i+dx[k],jj=j+Dy[k]; Link (i+j* -, ii+jj* -,1); } } } } if(s[i][j]=='I') { for(intk=0;k<4; k++) { if(Judge (i+dx[k],j+Dy[k])) { if(s[i+dx[k]][j+dy[k]]=='N') { intii=i+dx[k],jj=j+Dy[k]; Link (i+j* -+ +, ii+jj* -,1); } } } } if(s[i][j]=='N') {Link (i+j* -,4001,1); }}} printf ("%d\n", Dinic (4000,4001)); return 0;}
Codeforces Gym 100203I i-i WIN network flow Max Stream