题目链接:
思路:如果从某一根柱子能够直接跳到迷宫的外面,那么我们就将这个点连接到汇点。对于哪些不能跳出去但是又有柱子的点,那么 我们就去按照跳跃距离搜寻有没有其他的柱子能够去跳跃,如果能够找到的话,那么连接这两点,并且将容量控制为弧尾节点的柱子数,也正是由于一条弧只能够约 束一个顶点,所以我们需要进行拆点,点内之间流量为本身柱子数。
1 #include2 #include 3 #include 4 #include 5 using namespace std; 6 #define MAXN 2222 7 #define MAXM 2222222 8 #define inf 1<<30 9 struct Edge{ 10 int v,cap,next; 11 }edge[MAXM]; 12 int head[MAXN]; 13 int pre[MAXN]; 14 int cur[MAXN]; 15 int level[MAXN]; 16 int gap[MAXN]; 17 int n,m,d,vs,vt,NE,NV; 18 19 void Insert(int u,int v,int cap,int cc=0){ 20 edge[NE].v=v;edge[NE].cap=cap; 21 edge[NE].next=head[u];head[u]=NE++; 22 23 edge[NE].v=u;edge[NE].cap=cc; 24 edge[NE].next=head[v];head[v]=NE++; 25 } 26 27 int sap(int vs,int vt){ 28 memset(pre,-1,sizeof(pre)); 29 memset(level,0,sizeof(level)); 30 memset(gap,0,sizeof(gap)); 31 memcpy(cur,head,sizeof(head)); 32 int u=pre[vs]=vs,aug=inf,maxflow=0; 33 gap[0]=NV; 34 while(level[vs] =n||jj<0||jj>=m)continue;104 else if(ii==i&&jj==j)continue;105 else if(mat[ii][jj]==0)continue;106 Insert(2*mat[i][j],2*mat[ii][jj]-1,inf);107 }108 }109 if(i <=d||m-j<=d)Insert(2*mat[i][j],vt,inf);110 }111 }112 int ans=sum-sap(vs,vt);113 printf("Case #%d: ",t++);114 if(ans==0){115 printf("no lizard was left behind.\n");116 }else if(ans==1){117 printf("1 lizard was left behind.\n");118 }else {119 printf("%d lizards were left behind.\n",ans);120 }121 }122 return 0;123 }