HDU-4859-海岸線(最大流最小割)

鏈接http://acm.hdu.edu.cn/showproblem.php?pid=4859



#include <bits/stdc++.h>
#define MAXN 30007
#define MAXM 30007
using namespace std;
#define INF 0x3f3f3f3f
struct node
{
    int u,v,next,flow;
}edge[MAXM];
int head[3007],deep[3007],ind;
char mp[60][60];
int dir[4][2]={{1,0},{0,1},{-1,0},{0,-1}};
void add_edge(int u, int v, int c)
{
    edge[ind].v=v;
    edge[ind].flow=c;
    edge[ind].next=head[u];
    head[u]=ind++;
    edge[ind].v=u;
    edge[ind].flow=0;
    edge[ind].next=head[v];
    head[v]=ind++;
}
bool BFS(int S, int T)
{
    memset(deep,0,sizeof(deep));
    deep[S]=1;
    queue<int> q;
    q.push(S);
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        for(int i=head[u]; i+1; i=edge[i].next)
        {
            int v=edge[i].v;
            if(!deep[v] && edge[i].flow>0)
            {
                deep[v]=deep[u]+1;
                q.push(v);
                if(v==T)return 1;
            }
        }
    }
    return 0;
}
int DFS(int S, int T, int MAX_)
{
    if(S==T)return MAX_;
    int ans=0,f;
    for(int i=head[S]; i+1; i=edge[i].next)
    {
        int v=edge[i].v;
        if(deep[S]+1==deep[v] && edge[i].flow>0)
        {
            f=DFS(v,T,min(MAX_-ans,edge[i].flow));
            edge[i].flow-=f;
            edge[i^1].flow+=f;
            ans+=f;
            if(ans==MAX_)break;
        }
    }
    if(!ans)deep[S]=0;
    return ans;
}
int dinic(int S, int T)
{
    int ans=0,t;
    while(BFS(S,T))
        while(t=DFS(S,T,INF))
            ans+=t;
    return ans;
}

int main()
{
    int T,cas=1;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        memset(head,-1,sizeof(head));
        ind=0;
        scanf("%d%d",&n,&m);
        for(int i=1; i<=n; ++i)
            scanf("%s",mp[i]+1);
        m+=2,n+=2;
        int S=n*m+1,T=n*m+2;
        for(int i=0; i<n; ++i)
        {
            for(int j=0; j<m; ++j)
            {
              if(i==0||j==0||i==n-1||j==m-1)mp[i][j]='D';
                int poi=i*m+j;
                if(mp[i][j]=='D')
                {
                    if((i+j)&1)add_edge(S,poi,INF);
                    else add_edge(poi,T,INF);
                }
                if(mp[i][j]=='.')
                {
                    if((i+j)&1)add_edge(poi,T,INF);
                    else add_edge(S,poi,INF);
                }
                int x,y,f;
                for(int k=0; k<4; ++k)
                {
                    x=i+dir[k][0];
                    y=j+dir[k][1];
                    if(x<0||y<0||x>=n||y>=m)continue;
                    f=x*m+y;
                    add_edge(poi,f,1);
                }
            }
        }
        int ans=dinic(S,T);
        ans=n*(m-1)+(n-1)*m-ans;
        printf("Case %d: %d\n",cas++,ans);
    }
    return 0;
}
/*
4
2 2
EE
EE

3 3
EEE
.E.
EEE

3 3
EEE
DED
EEE

3 3
EEE
EEE
EEE
*/




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章