[ZJOI2009]狼和羊的故事
十多年前的省选题,还是浙江的省选……沧海桑田啊……
很简单一道题,网络流建模的应用,话说好像有很多题都是这样,在一个奇怪的方格上有各种奇怪的条件,数据范围还贼小,然后简单建模后直接跑网络流,更重要的是它们还都是可可爱爱的紫题……
唯一令我疑惑的是为什么它的N要开到两倍。
#include<cstdio>
#include<cstring>
//#define zczc
using namespace std;
const int N=205;
const int M=N*N;
const int maxn=1e9;
inline void read(int &wh){
wh=0;int f=1;char w=getchar();
while(w<'0'||w>'9'){if(w=='-')f=-1;w=getchar();}
while(w<='9'&&w>='0'){wh=wh*10+w-'0';w=getchar();}
wh*=f;return;
}
inline int min(int s1,int s2){
return s1<s2?s1:s2;
}
int s,t,cnt,m,n,in,id[N][N];
struct edge{
int t,v,next;
}e[M<<4];
int head[M],esum=1;
inline void adde(int fr,int to,int val){
e[++esum]=(edge){to,val,head[fr]};head[fr]=esum;
}
inline void add(int fr,int to,int val){
if(fr==0||to==0||fr>cnt||to>cnt)return;
adde(fr,to,val);adde(to,fr,0);
}
int f[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
int d[M],q[M],l,r;
bool check(int wh){
memset(d,0,sizeof(d));
d[q[l=r]=s]=1;
while(l<=r)
for(int i=head[wh=q[l++]],th;i;i=e[i].next)
if(e[i].v&&d[th=e[i].t]==0)d[th]=d[wh]+1,q[++r]=th;
return d[t];
}
int dinic(int wh,int val){
if(wh==t)return val;
int cost=0;
for(int i=head[wh],th;i;i=e[i].next){
if(e[i].v==0||d[th=e[i].t]!=d[wh]+1)continue;
int now=dinic(th,min(val,e[i].v));
val-=now,cost+=now,e[i].v-=now,e[i^1].v+=now;
}
return d[wh]=val?0:d[wh],cost;
}
signed main(){
#ifdef zczc
freopen("in.txt","r",stdin);
#endif
read(m);read(n);
s=++cnt;t=++cnt;
for(int i=1;i<=m;i++)for(int j=1;j<=n;j++)id[i][j]=++cnt;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++){
read(in);
if(in==1)add(s,id[i][j],maxn);
if(in==2)add(id[i][j],t,maxn);
for(int k=0;k<4;k++)add(id[i][j],id[i+f[k][0]][j+f[k][1]],1);
}
}
int ans=0;
while(check(0))ans+=dinic(s,maxn);
printf("%d\n",ans);
return 0;
}
一如既往,万事胜意