[BZOJ1412]狼和羊的故事

BZOJ1412
其實很容易想到割啦.然後再想一想就可以想到最小割啦.
割就是你選定一些邊,把這些邊去掉使得源點與匯點不連通.完全符合題目的意思呀.
又最小割等於最大流,跑一遍最大流就行啦

#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define maxn 10500
#define inf 0x3f3f3f3f
using namespace std;
struct node{
    int to,f,m;
    node*rev,*next;
}*con[maxn];
int gox[5]={0,0,-1,1},goy[5]={1,-1,0,0};
void addedge(int x,int y,int mm)
{
    node*p=new node;
    p->to=y;p->f=0;p->m=mm;
    p->next=con[x];con[x]=p;
    p=new node;
    p->to=x;p->f=p->m=0;
    p->next=con[y];con[y]=p;
    con[x]->rev=con[y];
    con[y]->rev=con[x];
}
int n,m,a[110][110],s,t;
int dl[maxn*100],de[maxn],head,tail,v;
int poi(int x,int y)
{return (x-1)*m+y;}
bool pd(int x,int y)
{
    if(x<1||x>n||y<1||y>m) return false;
    return true;
}
bool bfs()
{
    bool tmp=false;
    head=tail=1;dl[tail]=s;
    memset(de,-1,sizeof(de));
    de[s]=1;
    while(head<=tail)
    {
        v=dl[head++];
        if(v==t) tmp=true;
        for(node*p=con[v];p;p=p->next)
        if(p->f<p->m&&de[p->to]==-1)
        dl[++tail]=p->to,de[p->to]=de[v]+1;
    }
    return tmp;
}
int dinic(int v,int e)
{
    int o=0,temp=0;
    if(de[v]==-1) return 0;
    if(v==t) return e;
    for(node*p=con[v];p;p=p->next)
    {
    if(de[p->to]==de[v]+1&&p->f<p->m)
    {
        o=dinic(p->to,min(e-temp,p->m-p->f));
        temp+=o;
        p->f+=o;
        p->rev->f-=o;
    }
    if(temp==e) break;
    }
    if(temp==0) de[v]=-1;
    return temp;
}
int main()
{
    scanf("%d%d",&n,&m);
    s=0;t=n*m+1;
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    scanf("%d",&a[i][j]);
    for(int i=1;i<=n;++i)
    for(int j=1;j<=m;++j)
    {
        if(a[i][j]==1) {
            addedge(s,poi(i,j),inf);
            for(int k=0;k<4;++k)
            {
            int xx=i+gox[k],yy=j+goy[k];
            if(!pd(xx,yy)) continue;
            if(a[xx][yy]!=1) addedge(poi(i,j),poi(xx,yy),1) ;
            }
        }
        if(a[i][j]==0) 
            for(int k=0;k<4;++k)
            {
                int xx=i+gox[k],yy=j+goy[k];
                if(!pd(xx,yy)) continue;
                if(a[xx][yy]==2||a[xx][yy]==0) addedge(poi(i,j),poi(xx,yy),1);
            }
        if(a[i][j]==2)
            addedge(poi(i,j),t,inf);        
    }

    int ans=0;
    while(bfs())
    ans+=dinic(s,inf);
    cout<<ans;
    return 0;
}
發佈了29 篇原創文章 · 獲贊 0 · 訪問量 5239
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章