hdoj4859海岸线

1.地图周围再加一圈海

2.周长最多为sum=n*(m+1)+m*(n+1)。如果有邻接相同,要减1.最小割使相同最少。结果为sum-最小割

3.但是有E海滩,两边都能选。让E到S,T都连一个很大的数(10000,比最小割大就行)。这样最小割时两个10000一定要选一个。那么在sum中也加上10000就能消除。这样一定割一边而且不都割。而且连S,和T都为一样的数能确保消去E的决策的干扰。

剩下的就和套路一样了,奇偶建图,偶数时,'.'连S     INF,'D'连T   INF,E连S,T     10000。邻接互相连1。

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <vector>
#include <iomanip>
#include <cstring>
#include <map>
#include <queue>
#include <set>
#include <cassert>
#include <stack>
#include <bitset>
#define mkp make_pair
using namespace std;
const double EPS=1e-12;
typedef long long lon;
const lon SZ=51,SSZ=12*SZ*SZ,APB=10000,one=1,INF=0x7FFFFFFF,mod=1000000007;
lon n,m,S=2501,T=2502,sum,cnt,head[SZ*SZ];
lon nex[SSZ],to[SSZ],wt[SSZ],dep[SSZ];
int dx[]={0,1},dy[]={1,0};
char ch[SZ][SZ];

void add(int u,int v,int w)
{
    ++cnt;
    nex[cnt]=head[u];
    head[u]=cnt;
    to[cnt]=v,wt[cnt]=w;
}

int getid(int i,int j)
{
    return (i-1)*(m+2)+j;
}

void init()
{
    cin>>n>>m;
    sum=n*(m+1)+m*(n+1),cnt=-1;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n+2;++i)
    {
        for(int j=1;j<=m+2;++j)
        {
            if(i==1||j==1||i==n+2||j==m+2)
            {
                ch[i][j]='D';
            }
            else
            {
                cin>>ch[i][j];
                if(ch[i][j]=='E')sum+=APB;
            }
        }
    }
    for(int i=1;i<=n+2;++i)
    {
        for(int j=1;j<=m+2;++j)
        {
            if(!((i+j)&1))
            {
                if(ch[i][j]=='.')
                {
                    add(S,getid(i,j),INF);
                    add(getid(i,j),S,0);
                }
                else if(ch[i][j]=='D')
                {
                    add(getid(i,j),T,INF);
                    add(T,getid(i,j),0);
                }
                else
                {
                    add(S,getid(i,j),APB);
                    add(getid(i,j),S,0);
                    add(getid(i,j),T,APB);
                    add(T,getid(i,j),0);
                }
            }
            else
            {
                if(ch[i][j]=='.')
                {
                    add(getid(i,j),T,INF);
                    add(T,getid(i,j),0);
                }
                else if(ch[i][j]=='D')
                {
                    add(S,getid(i,j),INF);
                    add(getid(i,j),S,0);
                }
                else
                {
                    add(S,getid(i,j),APB);
                    add(getid(i,j),S,0);
                    add(getid(i,j),T,APB);
                    add(T,getid(i,j),0);
                }
            }
        }
    }
    for(int i=1;i<=n+1;++i)
    {
        for(int j=1;j<=m+1;++j)
        {
            for(int k=0;k<2;++k)
            {
                int nx=i+dx[k],ny=j+dy[k];
                if(i==1&&nx==1||j==1&&ny==1)continue;
                add(getid(i,j),getid(nx,ny),1);
                add(getid(nx,ny),getid(i,j),0);
                add(getid(nx,ny),getid(i,j),1);
                add(getid(i,j),getid(nx,ny),0);
            }
        }
    }
//    for(int i=1;i<=n+2;++i)
//    {
//        for(int j=1;j<=m+2;++j)
//        {
//            for(int k=head[getid(i,j)];k!=-1;k=nex[k])
//            {
//                cout<<i<<" "<<j<<" "<<to[k]<<" "<<wt[k]<<endl;
//            }
//        }
//    }
}

bool bfs()
{
    memset(dep,0,sizeof(dep));
    dep[S]=1;
    queue<int> q;
    q.push(S);
    for(;q.size();)
    {
        int fr=q.front();
        q.pop();
        for(int i=head[fr];i!=-1;i=nex[i])
        {
            int t=to[i],w=wt[i];
            if(!dep[t]&&w)
            {
                dep[t]=dep[fr]+1;
                q.push(t);
                if(t==T)return 1;
            }
        }
    }
    return 0;
}

int dinic(int x,int flow)
{
    if(x==T)return flow;
    else
    {
        int rem=flow;
        for(int i=head[x];i!=-1&&rem;i=nex[i])
        {
            int t=to[i],w=wt[i];
            if(dep[t]==dep[x]+1&&w)
            {
                int tmp=dinic(t,min(w,rem));
                if(!tmp)dep[t]=0;
                rem-=tmp;
                wt[i]-=tmp;
                wt[i^1]+=tmp;
            }
        }
        return flow-rem;
    }
}

void work()
{
    int res=0;
    for(;bfs();)
    {
        res+=dinic(S,INF);
    }
    cout<<sum-res<<endl;
}

void release()
{
    
}

int main()
{
    std::ios::sync_with_stdio(0);
    //freopen("d:\\1.txt","r",stdin);
    lon casenum;
    cin>>casenum;
    //cout<<casenum<<endl;
    for(int time=1;time<=casenum;++time)
    //for(int time=1;cin>>n>>m,n;++time)
    {
        cout<<"Case "<<time<<": ";
        init();
        work();
        release();
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/gaudar/p/10744044.html