Description
有一个M * N的棋盘,有的格子是障碍。现在你要选择一些格子来放置一些士兵,一个格子里最多可以放置一个士兵,障碍格里不能放置士兵。我们称这些士兵占领了整个棋盘当满足第i行至少放置了Li个士兵, 第j列至少放置了Cj个士兵。现在你的任务是要求使用最少个数的士兵来占领整个棋盘。
Input
第一行两个数M, N, K分别表示棋盘的行数,列数以及障碍的个数。 第二行有M个数表示Li。 第三行有N个数表示Ci。 接下来有K行,每行两个数X, Y表示(X, Y)这个格子是障碍。
Output
输出一个数表示最少需要使用的士兵个数。如果无论放置多少个士兵都没有办法占领整个棋盘,输出”JIONG!” (不含引号)
Sample Input
4 4 4
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
1 1 1 1
0 1 0 3
1 4
2 2
3 3
4 3
Sample Output
4
数据范围
M, N <= 100, 0 <= K <= M * N
数据范围
M, N <= 100, 0 <= K <= M * N
一眼看过去,这不是带下界的网络流吗?
然后各种GG.
原来下界可以通过减法转为上界,还顺便把大小关系转换过来了。
ACcode:
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define maxn 105
#define maxp 205
#define inf 0x3f3f3f3f
#define maxm maxn*maxn*10
using namespace std;
int n,m,k;
int info[maxp],to[maxm],Prev[maxm],cap[maxm],cnt_e=1;
inline void Node(int u,int v,int c){ Prev[++cnt_e]=info[u],info[u]=cnt_e,to[cnt_e]=v,cap[cnt_e]=c; }
inline void Line(int u,int v,int c){ Node(u,v,c),Node(v,u,0); }
int S,T,stm,vd[maxp],d[maxp],w[2][maxn];
bool ban[maxp][maxp];
int aug(int now,int Max)
{
if(now==T)
return Max;
int inc,Min=T-1,st=Max;
for(int i=info[now];i;i=Prev[i])
if(cap[i])
{
if(d[to[i]]+1==d[now])
{
inc=aug(to[i],min(cap[i],st));
st-=inc,cap[i]-=inc,cap[i^1]+=inc;
if(!st || d[S]>=T) return Max-st;
}
Min=min(Min,d[to[i]]);
}
if(Max==st)
{
(!--vd[d[now]]) && (d[S]=T);
++vd[d[now]=Min+1];
}
return Max-st;
}
int sap()
{
memset(vd,0,sizeof vd);
memset(d,0,sizeof d);
for(vd[0]=T,stm=0;d[S]<T;)
stm+=aug(S,inf);
return stm;
}
int main()
{
int u,v;
scanf("%d%d%d",&n,&m,&k);
S=n+m+1,T=S+1;
for(int i=1;i<=n;i++) scanf("%d",&w[0][i]),w[0][i]=m-w[0][i];
for(int i=1;i<=m;i++) scanf("%d",&w[1][i]),w[1][i]=n-w[1][i];
for(int i=1;i<=k;i++)
{
scanf("%d%d",&u,&v);
w[0][u]--,w[1][v]--;
ban[u][v+n]=1;
}
bool ERROR=0;
for(int i=1;i<=n;i++)
if(w[0][i]<0){ ERROR=1;break;}
else Line(S,i,w[0][i]);
if(ERROR){ puts("JIONG!");return 0; }
for(int i=1;i<=m;i++)
if(w[1][i]<0){ ERROR=1;break; }
else Line(i+n,T,w[1][i]);
if(ERROR){ puts("JIONG!");return 0; }
for(int i=1;i<=n;i++)
for(int j=1+n;j<=n+m;j++)
if(!ban[i][j])
Line(i,j,inf);
printf("%d\n",n*m-k-sap());
}