[最大流]BZOJ 1066——[SCOI2007]蜥蜴
2017-07-02 19:05
369 查看
1066: [SCOI2007]蜥蜴
题目描述
在一个r行c列的网格地图中有一些高度不同的石柱,一些石柱上站着一些蜥蜴,你的任务是让尽量多的蜥蜴逃到边界外。 每行每列中相邻石柱的距离为1,蜥蜴的跳跃距离是d,即蜥蜴可以跳到平面距离不超过d的任何一个石柱上。石柱都不稳定,每次当蜥蜴跳跃时,所离开的石柱高度减1(如果仍然落在地图内部,则到达的石柱高度不变),如果该石柱原来高度为1,则蜥蜴离开后消失。以后其他蜥蜴不能落脚。任何时刻不能有两只蜥蜴在同一个石柱上。解题思路
比较裸的网络流,每个节点有高度可以把点拆掉新建容量为高度的边权,建超级源连接所有L节点,容量为1,建超级汇连接所有可以跳出边界的节点,其容量和互相到达的节点之间建的容量都为无限大,然后直接刷Dinic就可以了。#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxv=805,maxm=1000005,MAXINT=2147483647; int n,m,d,tot,lnk[maxv],que[maxv],sum,hed,til,dis[maxv],s,t,B[maxv]; int cap[maxm],flw[maxm],son[maxm],nxt[maxm]; bool vis[maxv]; inline char _read(){ char ch=getchar(); while ((ch<'0'||ch>'9')&&ch!='.'&&ch!='L') ch=getchar(); return ch; } int sqr(int x){return x*x;} int getid(int i,int j,int k){return ((i-1)*m+j-1)*2+k;} int getl(int x1,int y1,int x2,int y2){return sqr(x1-x2)+sqr(y1-y2);} void add(int x,int y,int z){ nxt[tot]=lnk[x];lnk[x]=tot;son[tot]=y;cap[tot]=z;tot++; nxt[tot]=lnk[y];lnk[y]=tot;son[tot]=x;cap[tot]=0;tot++; } void maker(){ for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (_read()=='L') add(s,getid(i,j,1),1),sum++; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (i<=d||j<=d||(n-i+1)<=d||(m-j+1)<=d) add(getid(i,j,2),t,maxv); for (int i1=1;i1<=n;i1++) for (int j1=1;j1<=m;j1++) for (int i2=1;i2<=n;i2++) for (int j2=1;j2<=m;j2++) if ((i1!=i2||j1!=j2)&&getl(i1,j1,i2,j2)<=sqr(d)) add(getid(i1,j1,2),getid(i2,j2,1),maxv); } bool BFS(){ memset(vis,0,sizeof(vis)); memset(dis,63,sizeof(dis)); hed=0,til=1;que[1]=s;vis[s]=1;dis[s]=1; while (hed!=til){ int x=que[++hed]; for (int j=lnk[x];j!=-1;j=nxt[j]) if (!vis[son[j]]&&cap[j]>flw[j]){ dis[son[j]]=dis[x]+1; vis[son[j]]=1;que[++til]=son[j]; } } return vis[t]; } int DFS(int x,int mi){ if (x==t||!mi) return mi; int num=0; for (int &j=B[x];j!=-1;j=nxt[j]) if (dis[x]+1==dis[son[j]]){ int now=DFS(son[j],min(mi,cap[j]-flw[j])); if (now){ flw[j]+=now;flw[j^1]-=now; num+=now;mi-=now; if (!mi) break; } } return num; } void Dinic(){ int ans=0; while (BFS()){ memcpy(B,lnk,sizeof(B)); ans+=DFS(s,MAXINT); } printf("%d\n",sum-ans); } int main(){ freopen("exam.in","r",stdin); freopen("exam.out","w",stdout); memset(lnk,255,sizeof(lnk)); scanf("%d%d%d",&n,&m,&d); s=0,t=2*n*m+1; for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) add(getid(i,j,1),getid(i,j,2),_read()-48); maker(); Dinic(); return 0; }
相关文章推荐
- [bzoj1066][SCOI2007]蜥蜴 最大流
- 【BZOJ】1066: [SCOI2007]蜥蜴(最大流)
- bzoj1066: [SCOI2007]蜥蜴 最大流
- bzoj 1066: [SCOI2007]蜥蜴 (最大流)
- POJ 2711 Leapin' Lizards / HDU 2732 Leapin' Lizards / BZOJ 1066 [SCOI2007]蜥蜴(网络流,最大流)
- 【最大流】[SCOI2007]蜥蜴 BZOJ 1066
- [BZOJ1066][SCOI2007]蜥蜴(最大流)
- BZOJ 1066 [SCOI2007]蜥蜴(最大流)
- (bzoj 1066 [SCOI2007]蜥蜴)<网络最大流>
- BZOJ 1066: [SCOI2007]蜥蜴 网络最大流
- [BZOJ 1066] [SCOI2007] 蜥蜴 【最大流】
- 【BZOJ1066】[SCOI2007]蜥蜴【最大流】
- BZOJ 1066: [SCOI2007]蜥蜴 最大流
- [最大流] BZOJ1066: [SCOI2007]蜥蜴
- bzoj 1066: [SCOI2007]蜥蜴(最大流)
- BZOJ 1066: [SCOI2007]蜥蜴( 最大流 )
- poj 2711 Leapin' Lizards && BZOJ 1066: [SCOI2007]蜥蜴 最大流
- Bzoj 1066: [SCOI2007]蜥蜴(最大流)
- BZOJ 1066: [SCOI2007]蜥蜴 最大流
- BZOJ 1066 SCOI 2007 蜥蜴 最大流