题意:一个矩阵里有n*m个方格,有些方格中有l长的柱子,没相邻的两个柱子间的间距是1m,有些柱子上面有蜥蜴,现在你的目的是要使这些蜥蜴尽可能多的跳出到方格以为,假设蜥蜴每次能跳d远,但是它每离开一根柱子,柱子的高度就会降低1m,问最多能有多少只跳不出去。。。
#include<iostream> #include<algorithm> #include<cstdio> #include<cstring> #include<memory.h> using namespace std; const int M=2002; const int INF=2100000000; int t,n,m,tol; int gap[M],dis[M],pre[M],head[M],cur[M]; int NE,NV,mat[22][22],map[22][22]; char map2[22][22],str[22]; struct Node { int c,pos,next; } E[M*50]; int dx[]= {0,0,-1,1,0,0,-1,-1,1,1,-2,2,0,0,-1,-1,-2,-2,-3,1,1,2,2,3, 0,0,-1,-1,-2,-2,-3,-3,-4,1,1,2,2,3,3,4 };//0->3 4->11,12->23 int dy[]= {1,-1,0,0,-2,2,-1,1,-1,1,0,0,-3,3,-2,2,-1,1,0,-2,2,-1,1,0, -4,4,-3,3,-2,2,-1,1,0,3,-3,2,-2,1,-1,0 }; #define FF(i,NV) for(int i=0;i<NV;i++) int sap(int s,int t) { //memset(pre,-1,sizeof(pre)); memset(dis,0,sizeof(int)*(NV+1)); memset(gap,0,sizeof(int)*(NV+1)); FF(i,NV) cur[i] = head[i]; int u = pre[s] = s,maxflow = 0,aug =INF; gap[0] = NV; while(dis[s] < NV) { loop: for(int &i = cur[u]; i != -1; i = E[i].next) { int v = E[i].pos; if(E[i].c && dis[u] == dis[v] + 1) { aug=min(aug,E[i].c); pre[v] = u; u = v; if(v == t) { maxflow += aug; for(u = pre[u]; v != s; v = u,u = pre[u]) { E[cur[u]].c -= aug; E[cur[u]^1].c += aug; } aug =INF; } goto loop; } } int mindis = NV; for(int i = head[u]; i != -1 ; i = E[i].next) { int v = E[i].pos; if(E[i].c && mindis > dis[v]) { cur[u] = i; mindis = dis[v]; } } if( (--gap[dis[u]]) == 0) break; gap[ dis[u] = mindis+1 ] ++; u = pre[u]; } return maxflow; } void addEdge(int u,int v,int c ) { E[NE].c = c; E[NE].pos = v; E[NE].next = head[u]; head[u] = NE++; E[NE].c = 0; E[NE].pos = u; E[NE].next = head[v]; head[v] = NE++; } int main() { cin>>t; int i,j,k,len,sum,cas=1; while(t--) { cin>>n>>m; tol=0; sum=0; NE=0; memset(head,-1,sizeof(head)); memset(mat,0,sizeof(mat)); memset(map,0,sizeof(map));//因为没有赋初值WA了一上午。。。。。囧 for(i=0; i<n; i++) { scanf("%s",str); len=strlen(str); for(int j=0; j<len; j++) map[i][j]=str[j]-'0'; } for(i=0; i<n; i++) scanf("%s",&map2[i]); for(i=0; i<=n; i++) { for(j=0; j<len; j++) { if(map[i][j]) { if(map2[i][j]=='L') { mat[i][j]=++tol; sum++; addEdge(0,tol*2-1,1); addEdge(2*tol-1,tol*2,map[i][j]); continue; } mat[i][j]=++tol; addEdge(2*tol-1,2*tol,map[i][j]); } } } int sink=tol*2+1; NV=sink+1; int l; if(m==1)l=3; else if(m==2)l=11; else if(m==3) l=23; // else l=-1; for(i=0; i<n; i++) { for(j=0; j<len; j++) { if(map[i][j]>0) { int Min=min(min(i,n-i-1),min(j,len-j-1)); if(m>Min) addEdge(mat[i][j]*2,sink,INF); int x,y; for(int tt=0; tt<=l; tt++) { x=i+dx[tt]; y=j+dy[tt]; if(x>=0&&x<n&&y>=0&&y<len&&map[x][y]>0) { addEdge(mat[i][j]*2,mat[x][y]*2-1,INF); } } } } } sum=sum-sap(0,sink); if(sum>1) printf("Case #%d: %d lizards were left behind.\n",cas++,sum); else if(sum==0) printf("Case #%d: no lizard was left behind.\n",cas++); else printf("Case #%d: 1 lizard was left behind.\n",cas++); } return 0; }