BZOJ 1458 士兵占领 Dinic最大流

来源:互联网 发布:数据配线架价格 编辑:程序博客网 时间:2024/05/08 23:16

题目大意:给定一个m*n的棋盘,其中k个点有障碍,要求放置最少的士兵,使第i行有至少L[i]个,第j列有至少C[j]个

首先这种问题很明显的网络流 但是正图肯定是跑不了 限制条件是至少而且要求放置的也是最少 很难解决

反向考虑 将棋盘上先放满士兵 此时若不能满足条件则无解 然后求最多能撤掉多少个士兵 其中第i行最多撤去templ[i]-l[i]个士兵 templ[i]表示第i行当前放置的士兵个数

尼玛我的网络流是多久不写了……居然没连反向弧就跑样例……最逗的是数组开小一倍不报RE报WA……

#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#define M 110#define s 0#define t (m+n+1)#define INF 0x3f3f3f3fusing namespace std;struct abcd{    int to,f,next;}table[M*M<<1];int head[M+M],tot=1;int m,n,k,ans;int l[M],c[M];int templ[M],tempc[M];bool ban[M][M];int d[M+M];void Add(int x,int y,int z){    table[++tot].to=y;    table[tot].f=z;    table[tot].next=head[x];    head[x]=tot;}bool BFS(){    int i;    static int q[65540];    static unsigned short r,h;    r=h=0;    memset(d,-1,sizeof d);    d[s]=0;q[++r]=s;    while(r!=h)    {        int x=q[++h];        for(i=head[x];i;i=table[i].next)            if(table[i].f)            {                if(~d[table[i].to])                    continue;                d[table[i].to]=d[x]+1;                q[++r]=table[i].to;                if(table[i].to==t)                    return true;            }    }    return false;}int Dinic(int x,int flow){    int i,left=flow;    if(x==t)        return flow;    for(i=head[x];i&&left;i=table[i].next)        if(table[i].f&&d[table[i].to]==d[x]+1)        {            int temp=Dinic(table[i].to,min(left,table[i].f));            if(!temp) d[table[i].to]=-1;            left-=temp;            table[i].f-=temp;            table[i^1].f+=temp;        }    return flow-left;}int main(){    int i,j,x,y;    cin>>m>>n>>k;    for(i=1;i<=m;i++)        scanf("%d",&l[i]),templ[i]=n;    for(i=1;i<=n;i++)        scanf("%d",&c[i]),tempc[i]=m;    for(i=1;i<=k;i++)    {        scanf("%d%d",&x,&y);        if(--templ[x]<l[x])        {            puts("JIONG!");            return 0;        }        if(--tempc[y]<c[y])        {            puts("JIONG!");            return 0;        }        ban[x][y]=true;    }    ans=m*n-k;    for(i=1;i<=m;i++)        for(j=1;j<=n;j++)            if(!ban[i][j])                Add(i,m+j,1),Add(m+j,i,0);    for(i=1;i<=m;i++)        Add(s,i,templ[i]-l[i]),Add(i,s,0);    for(i=1;i<=n;i++)        Add(m+i,t,tempc[i]-c[i]),Add(t,m+i,0);    while( BFS() )        ans-=Dinic(s,INF);    cout<<ans<<endl;    }


1 0
原创粉丝点击