HDU 2732 最大流 拆点
来源:互联网 发布:启动股票池 板块数据 编辑:程序博客网 时间:2024/05/15 21:48
题意:矩阵里面有些蜥蜴要跳到外面,每一个规定了可以被经过的次数,每次跳的距离小于等于d,问最后还有多少蜥蜴留下
分析:最大流,ans=总蜥蜴数-最大流
把每个格子拆分成2个点,2点之间的容量为格子能被经过的次数,然后对每个格子向它在d步内能到达的格子添加容量为INF的边,能直接跳出的格子向终点添加容量为INF的边,起点到每个有蜥蜴的格子添加容量为1的边,ISAP求最大流
#include <iostream>#include<cstdio>#include<cstring>#include<algorithm>#define INF 0x7fffffff#define M 550000#define N 1005using namespace std;int map[N][N],head[N],cnt,nv;char map1[N][N],map2[N][N];struct edge{ int v,next,cap,flow;}e[M];void init(){ memset(head,-1,sizeof(head)); cnt=0;}void addedge(int u,int v,int cap){ e[cnt].v=v;e[cnt].cap=cap;e[cnt].flow=0;e[cnt].next=head[u];head[u]=cnt++; e[cnt].v=u;e[cnt].cap=0;e[cnt].flow=0;e[cnt].next=head[v];head[v]=cnt++;}int gap[N],dist[N],pre[N],curedge[N];int ISAP(int s,int t){ int cur_flow,u,tmp,neck,i,max_flow=0; memset(gap,0,sizeof(gap)); memset(pre,-1,sizeof(pre)); memset(dist,0,sizeof(dist)); for(i=1;i<=nv;i++){ curedge[i]=head[i]; } gap[nv]=nv; u=s; while(dist[s]<nv){ if(u==t){ cur_flow=INF; for(i=s;i!=t;i=e[curedge[i]].v){ if(cur_flow>e[curedge[i]].cap){ neck=i; cur_flow=e[curedge[i]].cap; } } for(i=s;i!=t;i=e[curedge[i]].v){ tmp=curedge[i]; e[tmp].cap-=cur_flow; e[tmp].flow+=cur_flow; tmp^=1; e[tmp].cap+=cur_flow; e[tmp].flow-=cur_flow; } max_flow+=cur_flow; u=neck; } for(i=curedge[u];i!=-1;i=e[i].next){ if(e[i].cap>0&&dist[u]==dist[e[i].v]+1) break; } if(i!=-1){ curedge[u]=i; pre[e[i].v]=u; u=e[i].v; }else { if(0==--gap[dist[u]]) break; curedge[u]=head[u]; for(tmp=nv,i=head[u];i!=-1;i=e[i].next){ if(e[i].cap>0) tmp=tmp<dist[e[i].v]?tmp:dist[e[i].v]; } dist[u]=tmp+1; ++gap[dist[u]]; if(u!=s) u=pre[u]; } } return max_flow;}int main(){ int total,vt,t,ics=0,n,m,sum,ans,i,j,d,x,y; scanf("%d",&t); while(t--){ scanf("%d%d",&n,&d); init(); memset(map,0,sizeof(map)); for(i=0;i<n;i++){ scanf("%s",map1[i]); } for(i=0;i<n;i++){ scanf("%s",map2[i]); } m=strlen(map2[0]); total=0; for(i=0;i<n;i++){ for(j=0;j<m;j++){ if(map1[i][j]>'0'){//拆点 map[i][j]=++total; addedge(total*2-1,total*2,map1[i][j]-'0'); } } } vt=total*2+1,nv=vt+1; sum=0; for(i=0;i<n;i++){ for(j=0;j<m;j++){ if(map2[i][j]=='L'){ sum++; addedge(0,map[i][j]*2-1,1); //源点跟有蜥蜴的点连边 } } } for(i=0;i<n;i++){ for(j=0;j<m;j++){ if(map[i][j]){ for(x=-d;x<=d;x++){ for(y=abs(x)-d;y<=d-abs(x);y++){ int ii=i+x; int jj=j+y; if(ii<0||jj<0||ii>=n||jj>=m) continue; if(ii==i&&jj==j) continue; if(!map[ii][jj]) continue; addedge(2*map[i][j],2*map[ii][jj]-1,INF); } } if(i<d||j<d||i>n-1-d||j>m-1-d){ addedge(map[i][j]*2,vt,INF); } } } } ans=sum-ISAP(0,vt); printf("Case #%d: ",++ics); if(ans) printf("%d",ans); else printf("no"); if(ans>1) printf(" lizards were left behind.\n"); else printf(" lizard was left behind.\n"); } return 0;}
0 0
- HDU 2732 最大流 拆点
- hdu 2732(最大流+拆点)
- hdu 2732 / poj 2711 Leapin' Lizards //拆点最大流
- HDU 2732 Leapin' Lizards(最大流+拆点)
- HDU 2732 Leapin' Lizards(拆点+最大流)
- HDU 2732 Leapin' Lizards(拆点+最大流)
- hdu 2732 Leapin' Lizards (拆点,最大流)
- hdu 2732 Leapin' Lizards 拆点最大流 isap
- HDU 2732 Leapin' Lizards (最大流,拆点)
- HDU 2732 Leapin' Lizards(拆点+最大流)
- HDU 3491 Thieves 【拆点+最大流】
- hdu 4292 拆点 最大流
- HDU 4289 Control(拆点,最大流)
- HDU 4292 Food(拆点,最大流)
- hdu 3277 二分+拆点最大流
- HDU 3036 拆点二分最大流
- HDU 4289 Control(拆点+最大流)
- hdu 4292(拆点+最大流)
- 静态方法和实例方法的区别
- Netty Server端代码简略分析
- JavaSE06_常用类之String
- fghnxrtghnxrthrth
- JavaSE06_常用类之StringBuilder
- HDU 2732 最大流 拆点
- 关于字典序列问题的一个脑洞->>
- JavaSE06_常用类之String StringBuffer StringBuilder比较
- 115个Java面试题和答案——终极列表
- 转ACE_Svc_Handler
- 从n个数中找出每个数的重复数
- vim全选复制
- JavaSE06_常用类之Math
- Netty使用初步