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

    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 <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <iostream>
    
    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<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 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
    ",dinic(4000,4001));
        return 0;
    }
  • 相关阅读:
    【python-leetcode142-快慢指针】环形链表2
    SpringMvc 拦截器
    什么是RESTful?RESTfule风格
    Http协议
    SpringMVC Mock测试
    Oracle 创建用户,赋予指定表名/视图只读权限
    添加junit和spring-test还是用不了@Test和@RunWith(SpringJUnit4ClassRunner.class)注解
    SpringMVC 数据交互
    SpringMvc commons-fileupload图片/文件上传
    SpringMvc 异常处理器
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4733312.html
Copyright © 2011-2022 走看看