题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732
题目大意:求最多可跳出地图的蜥蜴数,木桩在经过若干次跳跃后将不能使用。
题目思路:拆点,每个点容量为它的数字,然后按d的距离可以跳到的点建容量无穷的边,可以跳出去的点和汇点建容量无穷的边,源点和每个L建容量为1的边(摘录)
#include<stdio.h> #include<stdlib.h> #include<string.h> #include<string> #include<queue> #include<algorithm> #include<vector> #include<stack> #include<list> #include<iostream> #include<map> #include<math.h> using namespace std; #define inf 0x7f3f3f3f #define Max 1000 int max(int a,int b) { return a>b?a:b; } int min(int a,int b) { return a<b?a:b; } int dis[Max],gap[Max],pre[Max],cur[Max],p[Max]; int dx[4][2]={0,1,1,0,0,-1,-1,0}; char mp[22][22]; int n,m,s,t,eid; struct node { int to,next,c; }e[4*10*Max]; void addedge(int u,int v,int c) { e[eid].to=v; e[eid].c=c; e[eid].next=p[u]; p[u]=eid++; } int ISAP(int st,int ed,int n) ///起点,终点,顶点数 { memset(dis, 0, sizeof(dis)); memset(gap, 0, sizeof(gap)); gap[0]=n; memcpy(cur, p, sizeof(p)); ///memcpy! int i,flag,v,u=pre[st]=st,maxflow=0,aug=inf; //puts("akk"); while(dis[st] < n) { for(flag=0,i=cur[u];i!=-1; i=e[i].next) /// cur[u] if(e[i].c&& dis[u] == dis[e[i].to]+1) { flag = 1; break; } if(flag) { if(aug > e[i].c) aug = e[i].c; v = e[i].to; pre[v] = u; cur[u] = i; u = v; if(u == ed) { for(u=pre[u]; 1;u=pre[u]) ///notice! { e[cur[u]].c -= aug; e[cur[u]^1].c += aug; if(u==st) break; // puts("akkk"); } maxflow += aug; aug = inf; } } else { int minx = n; for(i=p[u]; i!=-1; i=e[i].next) if(e[i].c&& dis[e[i].to]<minx) { minx = dis[e[i].to]; cur[u] = i; } if(--gap[dis[u]] == 0) break; dis[u] = minx+1; gap[dis[u]]++; u = pre[u]; } } // printf("Case %d:\n%d\n",count,maxflow); return maxflow; } int main() { int m,n,t,count=1,d; int u,v,c,i,j,ii,jj,k,x,y; scanf("%d",&t); while(t--) { eid=0; memset(p,-1,sizeof(p)); scanf("%d%d",&n,&d); for(i=0;i<n;i++) { scanf("%s",mp[i]); m=strlen(mp[i]); for(j=0;j<m;j++) { if(mp[i][j]=='0') continue; addedge(n*m+i*m+j,i*m+j,mp[i][j]-'0'); addedge(i*m+j,n*m+i*m+j,0); for(x=i-d;x<=i+d;x++) for(y=j-d;y<=j+d;y++) { if((abs(i-x)+abs(j-y)>d)||(x==i&&y==j)) continue; if(x<0||y<0||x>=n||y>=m) { addedge(i*m+j,2*n*m+1,inf); addedge(2*n*m+1,i*m+j,0); // printf("i %d j %d\n",i,j); } else { addedge(i*m+j,n*m+x*m+y,inf); addedge(n*m+x*m+y,i*m+j,0); } } } } int ans=0; for(i=0;i<n;i++) { scanf("%s",mp[i]); for(j=0;j<m;j++) { if(mp[i][j]=='L') { addedge(2*m*n,n*m+i*m+j,1); addedge(n*m+i*m+j,2*m*n,0); ans++; } } } ans-=ISAP(2*n*m,2*n*m+1,2*n*m+2); printf("Case #%d: ",count++); if(ans>1) printf("%d lizards were left behind.\n",ans); if(ans==0) puts("no lizard was left behind."); if(ans==1) puts("1 lizard was left behind."); } }