zoj1654

Posted gaudar

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了zoj1654相关的知识,希望对你有一定的参考价值。

各行各列连续的o和*记为一个元素。然后记录下开始和结束位置。如果横条和竖条交点为‘o‘。连线。表示两边能选一边,然后最大流。

#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>
//#include <unordered_set>
#define mkp make_pair
#define err cout<<"here"<<endl
using namespace std;
const double EPS=1e-12;
typedef long long lon;
typedef unsigned long long ull;
typedef map<ull,int>::iterator IT;
const lon SZ=2510,SSZ=1000010,APB=4,mod=100000,one=97;
const lon INF=0x7FFFFFFF;
lon n,m,knum,cnt,S=2507,T=2508;
struct nd{
    lon to,wt;
    nd(lon a=0,lon b=0):to(a),wt(b){}
};
int dep[SZ],bg[SZ],fn[SZ],bel[SZ];
int nex[SSZ],head[SZ],wt[SSZ],to[SSZ];
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 gid(int x,int y)
{
    if(y==0)return x;
    else if(y==1)return x+n;
    else return x+n+m+1;
}

void init()
{
    cnt=-1;
    memset(head,-1,sizeof(head));
//    memset(bel,0,sizeof(bel));
//    memset(bg,0,sizeof(bg));
//    memset(fn,0,sizeof(fn));
    cin>>n>>m;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)cin>>ch[i][j];
    }
    int rnum=0,cnum=0;
    bool csc=0;
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m+1;++j)
        {
            if(ch[i][j]!=#&&j!=m+1&&!csc)
            {
                ++rnum;
                csc=1;
                bg[rnum]=j;
                bel[rnum]=i;
            }
            if((ch[i][j]==#||j==m+1)&&csc)
            {
                fn[rnum]=j-1;
                csc=0;
            }
        }
    }
    csc=0;
    for(int j=1;j<=m;++j)
    {
        for(int i=1;i<=n+1;++i)
        {
            if((ch[i][j]!=#&&i!=n+1)&&!csc)
            {
                ++cnum;
                csc=1;
                bg[rnum+cnum]=i;
                bel[rnum+cnum]=j;
            }
            if((ch[i][j]==#||i==n+1)&&csc)
            {
                fn[rnum+cnum]=i-1;
                csc=0;
            }
        }
    }
    for(int i=1;i<=rnum;++i)
    {
        for(int j=rnum+1;j<=rnum+cnum;++j)
        {
            bool ok=0;
            int x=bel[i],y=bel[j];
            ok|=ch[x][y]==o;
            ok&=bg[i]<=y&&y<=fn[i];
            ok&=bg[j]<=x&&x<=fn[j];
            if(ok)
            {
                add(i,j,1);
                add(j,i,0);
            }
        }
    }
    for(int i=1;i<=rnum;++i)
    {
        add(S,i,1);
        add(i,S,0);
    }
    for(int i=1+rnum;i<=cnum+rnum;++i)
    {
        add(i,T,1),add(T,i,0);
    }
    //cout<<rnum<<" "<<cnum<<endl;
}

bool bfs()
{
    memset(dep,0,sizeof(dep));
    queue<int> q;
    q.push(S);
    dep[S]=1;
    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);
            }
        }
    }
    return dep[T];
}

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(rem,w));
                if(tmp==0)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<<res<<endl;
}

void release()
{    
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        ch[i][j]=0;
    }
}

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

 

以上是关于zoj1654的主要内容,如果未能解决你的问题,请参考以下文章

ZOJ 1654--Place the Robots二分匹配 &amp;&amp; 经典建图

ZOJ 1654 Place the Robots建图思维(分块思想)+二分匹配

poj1654 Area

群赛 ZOJ3741(dp) ZOJ3911(线段树)

POJ1654 Area(多边形面积)

poj.1654Area(计算几何)