zoukankan      html  css  js  c++  java
  • Codeforces Gym 100203I I

    I - I WIN
    Time Limit: 2 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

               注意点考虑到有一个I可能会与两个不同位置的W,N相连 

    还有就是模版6666

    代码:

    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <algorithm>
    #include <set>
    #include <vector>
    #include <queue>
    #include <typeinfo>
    #include <map>
    #include <stack>
    typedef long long ll;
    using namespace std;
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //***************************
    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<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+=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]<mx)
                    {
                        mx=dis[E[it].v]; cur[u]=it;
                    }
                }
                if ((--gap[dis[u]])==0) break;
                ++gap[dis[u]=mx+1]; u=pre[u];
            }
            return maxflow;
        }
        bool bfs(int S,int T)
        {
            static int Q[MAXN]; memset(dis,-1,sizeof(dis[0])*N);
            dis[S]=0; Q[0]=S;
            for (int h=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;
                    }
                }
            }
            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<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; 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 mp[333][333];
    int ss[4][2]={-1,0,1,0,0,1,0,-1};
    int n,m;
    int main()
    {
        init(15000);
          n=read();
         m=read();
        for(int i=1; i<=n; i++)
        {
            scanf("%s",mp[i]+1);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++)
            if(mp[i][j]=='I'){
                link((i-1)*m+j,(i-1)*m+j+500,1);
            }
        }
        for(int i=1; i<=n; i++)
        {
            for(int j=1; j<=m; j++)
            {
                if(mp[i][j]=='W')
                {
                    //mpp[n*m+1][(i-1)*m+j]=1;
                    link(n*m+1+500,(i-1)*m+j,1);
                    for(int e=0; e<4; e++)
                        if(mp[i+ss[e][0]][j+ss[e][1]]=='I')
                        {
    
                            link((i-1)*m+j,(i+ss[e][0]-1)*m+j+ss[e][1],1);
                        }
                }
                if(mp[i][j]=='I')
                {
                    for(int e=0; e<4; e++)
                        if(mp[i+ss[e][0]][j+ss[e][1]]=='N')
                        {
                           link((i-1)*m+j+500,(i+ss[e][0]-1)*m+j+ss[e][1],1);
                        }
                }
                if(mp[i][j]=='N')link((i-1)*m+j,n*m+2+500,1);
            }
        }
        cout<<dinic(n*m+1+500,n*m+1+500+1)<<endl;
      return 0;
    }
  • 相关阅读:
    Angular入门到精通系列教程(12)- 路由(Routing)
    Angular入门到精通系列教程(11)- 模块(NgModule),延迟加载模块
    error: file '/boot/grub/i386-pc/normal.mod' not found解决方案
    mysql常用查询
    mysql数据库表中随机生成时间
    成本分析报表
    弹窗维护字段POPUP_GET_VALUES
    返回上一个屏幕
    PM停机时间问题处理
    IP41
  • 原文地址:https://www.cnblogs.com/zxhl/p/4733393.html
Copyright © 2011-2022 走看看