BZOJ1458 士兵佔領

思路:
上下界網絡流還是可以寫的吧。。。。
簡潔一點的方法應該是假設全部填滿,然後跑最大流看能夠刪掉多少

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
const int imax=100+9;
const int dmax=229;
const int bmax=100000+229;
const int inf=10000229;
int n,m,K,nlow[imax],mlow[imax],nlim[imax],mlim[imax];
int map[imax][imax];
int S,T,num,head[dmax],to[bmax],inext[bmax],re[bmax];

void iadd(int u,int v,int flow){
    to[num]=v; re[num]=flow; inext[num]=head[u]; head[u]=num++;
}
void add(int u,int v,int w){ iadd(u,v,w); iadd(v,u,0); }

void iread()
{
    scanf("%d%d%d",&n,&m,&K);
    for(int i=1;i<=n;i++) scanf("%d",&nlow[i]);
    for(int i=1;i<=m;i++) scanf("%d",&mlow[i]);
    for(int i=1;i<=K;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        map[a][b]=1; 
        nlim[a]++; mlim[b]++;
    }
}

bool build()
{
    S=0; T=n+m+1;
    memset(head,-1,sizeof(head));
    for(int i=1;i<=n;i++)
    {
        int nowv=nlim[i]+nlow[i];
        if(nowv>m) return false;
        add(S,i,m-nowv);    
    }
    for(int i=1;i<=m;i++)
    {
        int nowv=mlim[i]+mlow[i];
        if(nowv>n) return false;
        add(i+n,T,n-nowv);  
    }
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) 
            if(map[i][j]==0) add(i,n+j,1);  
    return 1;
}

int d[dmax]; 
queue<int> q; 
bool BFS()
{
    memset(d,0,sizeof(d));
    d[S]=1; q.push(S);
    while(!q.empty())
    {
        int u=q.front(); q.pop();
        for(int i=head[u];i!=-1;i=inext[i])
            if(re[i] && !d[to[i]])
            {
                d[to[i]]=d[u]+1;
                q.push(to[i]);  
            }
    }
    return d[T]!=0; 
}

int DFS(int x,int c)
{
    if(x==T || c==0) return c;
    int r=c;
    for(int i=head[x];i!=-1;i=inext[i])
        if(d[to[i]]==d[x]+1)
        {
            int f=DFS(to[i],min(re[i],r));
            r-=f; re[i]-=f; re[i^1]+=f;
            if(!r) break;   
        }   
    if(r==c) d[x]=0;
    return c-r;
}

void iwork()
{
    if(!build()) { puts("JIONG!"); return;} 
    int ans=n*m-K;
    while(BFS()) ans-=DFS(S,inf);
    printf("%d\n",ans); 
}

int main()
{
    iread();
    iwork(); 
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章