洛谷P2598 [ZJOI2009]狼和羊的故事

2018-02-03 19:47:34来源:cnblogs.com作者:自为风月马前卒人点击

分享

题目描述

“狼爱上羊啊爱的疯狂,谁让他们真爱了一场;狼爱上羊啊并不荒唐,他们说有爱就有方向......” Orez听到这首歌,心想:狼和羊如此和谐,为什么不尝试羊狼合养呢?说干就干! Orez的羊狼圈可以看作一个n*m个矩阵格子,这个矩阵的边缘已经装上了篱笆。可是Drake很快发现狼再怎么也是狼,它们总是对羊垂涎三尺,那首歌只不过是一个动人的传说而已。所以Orez决定在羊狼圈中再加入一些篱笆,还是要将羊狼分开来养。 通过仔细观察,Orez发现狼和羊都有属于自己领地,若狼和羊们不能呆在自己的领地,那它们就会变得非常暴躁,不利于他们的成长。 Orez想要添加篱笆的尽可能的短。当然这个篱笆首先得保证不能改变狼羊的所属领地,再就是篱笆必须修筑完整,也就是说必须修建在单位格子的边界上并且不能只修建一部分。

输入输出格式

输入格式:

文件的第一行包含两个整数n和m。接下来n行每行m个整数,1表示该格子属于狼的领地,2表示属于羊的领地,0表示该格子不是任何一只动物的领地。

输出格式:

文件中仅包含一个整数ans,代表篱笆的最短长度。

输入输出样例

输入样例#1: 复制
2 22 2 1 1 
输出样例#1: 复制
2

说明

数据范围

10%的数据 n,m≤3

30%的数据 n,m≤20

100%的数据 n,m≤100

最小割的模型

一开始傻逼了。。上来就把正解否定了。。

源点向狼连边

狼向羊连边(狼吃羊hhh)

羊向汇点连边

空地之间互相连边

狼向空地连边

空地向羊连边

#include<cstdio>#include<cstring>#include<queue>using namespace std;const int MAXN=200001,INF=2*1e9+10;inline char nc(){    static char buf[MAXN],*p1=buf,*p2=buf;    return p1==p2&&(p2=(p1=buf)+fread(buf,1,MAXN,stdin),p1==p2)?EOF:*p1++;}inline int read(){    char c=nc();int x=0,f=1;    while(c<'0'||c>'9'){if(c=='-')f=-1;c=nc();}    while(c>='0'&&c<='9'){x=x*10+c-'0';c=nc();}    return x*f;}int S=0,T=301;struct node{    int u,v,flow,nxt;}edge[MAXN*20];int head[MAXN],cur[MAXN],num=0;inline void add_edge(int x,int y,int z){    edge[num].u=x;    edge[num].v=y;    edge[num].flow=z;    edge[num].nxt=head[x];    head[x]=num++;}inline void AddEdge(int x,int y,int z) {    add_edge(x,y,z);    add_edge(y,x,0);}int deep[MAXN];inline bool BFS(){    memset(deep,0,sizeof(deep));    deep[S]=1;    queue<int>q;    q.push(S);    while(q.size()!=0)    {        int p=q.front();        q.pop();        for(int i=head[p];i!=-1;i=edge[i].nxt)            if(!deep[edge[i].v]&&edge[i].flow)            {                deep[edge[i].v]=deep[p]+1;q.push(edge[i].v);                if(edge[i].v==T) return 1;            }    }    return deep[T];}int DFS(int now,int nowflow){    if(now==T||nowflow<=0)    return nowflow;    int totflow=0;    for(int &i=cur[now];i!=-1;i=edge[i].nxt)     {        if(deep[edge[i].v]==deep[now]+1&&edge[i].flow)        {            int canflow=DFS(edge[i].v,min(nowflow,edge[i].flow));            edge[i].flow-=canflow;edge[i^1].flow+=canflow;            totflow+=canflow;            nowflow-=canflow;            if(nowflow<=0) break;        }    }    return totflow;}int Dinic(){    int ans=0;    while(BFS())    {        memcpy(cur,head,sizeof(head));         ans+=DFS(S,INF);    }    return ans;}int xx[6]={0,-1,+1,0,0},yy[6]={0,0,0,-1,+1};int a[1001][1001],belong[1001][1001];int N,M;int main(){    #ifdef WIN32    freopen("a.in","r",stdin);    #else    #endif    memset(head,-1,sizeof(head));    N=read();M=read();T=N*M+2;       for(int i=1;i<=N;i++)        for(int j=1;j<=M;j++)            a[i][j]=read(),belong[i][j]=(i-1)*M + j;    for(int i=1;i<=N;i++)        for(int j=1;j<=M;j++)        {            if(a[i][j]==1)             {                AddEdge(S,belong[i][j],INF);                for(int k=1;k<=4;k++)                    if( i+xx[k] >= 1 && i+xx[k] <= N && j+yy[k] >= 1 && j+yy[k]<=M && a[i][j] != a[i+xx[k]][j+yy[k]])                        AddEdge(belong[i][j],belong[i+xx[k]][j+yy[k]],1);            }            else if(a[i][j]==2)             {                AddEdge(belong[i][j],T,INF);                for(int k=1;k<=4;k++)                    if( i+xx[k] >= 1 && i+xx[k] <= N && j+yy[k] >= 1 && j+yy[k]<=M && a[i+xx[k]][j+yy[k]] == 0 )                        AddEdge(belong[i+xx[k]][j+yy[k]],belong[i][j],1);            }            else            {                for(int k=1;k<=4;k++)                    if( i+xx[k] >= 1 && i+xx[k] <= N && j+yy[k] >= 1 && j+yy[k]<=M && a[i+xx[k]][j+yy[k]] == 0)                        AddEdge(belong[i][j],belong[i+xx[k]][j+yy[k]],1);            }        }    printf("%d",Dinic());    return  0;}

相关文章

    无相关信息

最新文章

123

最新摄影

闪念基因

微信扫一扫

第七城市微信公众平台