有一些蜥蜴在一个迷宫里面,求这些蜥蜴还有多少是无论如何都逃不出来的。蜥蜴最远能够跳跃距离D,若某一时刻蜥蜴能跳到迷宫外围,则算>蜥蜴逃出来了。每只蜥蜴有一个初始的位置,题目保证这些位置都有一些柱子,每次蜥蜴从一个位置跳到另外一个位置的时候,就会由于反作用力使得一根
柱子倒下。每根柱子都有最大jump数,若有超过jump个蜥蜴从该跟柱子跳过(也就是leap次),则柱子会倒塌。距离是算曼哈顿距离。
建图:初始有蜥蜴的柱子和source连边,容量为1
每个柱子拆成两个点,u -> u',容量为jump数
能跳到外围的柱子和sink连边,容量infinite
相距不超过D的柱子u,v,连边u' -> v 和 v' -> u,容量infinite
const int inf = 1000000000 ; const int maxn = 20000 , maxm = 500000 ; struct Edge{ int v , f ,next ; Edge(){} Edge(int _v , int _f , int _next):v(_v) ,f(_f),next(_next){} }; int sourse , meet ; int id ; Edge e[maxm*2 + 10] ; int g[maxn + 10] ; void add(int u , int v , int f){ e[++id] = Edge(v , f ,g[u]) ; g[u] = id ; e[++id] = Edge(u , 0 , g[v]) ; g[v] = id ; } queue <int> que ; bool vis[maxn + 10] ; int dist[maxn + 10] ; void bfs(){ memset(dist , 0 , sizeof(dist)) ; while(! que.empty()) que.pop() ; que.push(sourse) ; vis[sourse] = 1 ; while(! que.empty()){ int u = que.front() ; que.pop() ; for(int i = g[u] ; i ; i = e[i].next){ int v = e[i].v ; if(e[i].f && !vis[v]){ que.push(v) ; dist[v] = dist[u] + 1 ; vis[v] = 1 ; } } } } int dfs(int u , int delta){ if(u == meet) return delta ; int ans = 0 ; for(int i = g[u] ; i && delta ; i = e[i].next){ int v = e[i].v ; if(e[i].f && dist[v] == dist[u] + 1){ int d = dfs(v , min(delta , e[i].f)) ; e[i].f -= d ; e[i^1].f += d ; delta -= d ; ans += d ; } } return ans ; } int maxflow(){ int ans = 0 ; while(1){ memset(vis , 0 , sizeof(vis)) ; bfs() ; if(! vis[meet]) return ans ; ans += dfs(sourse , inf) ; } } void init(){ memset(g , 0 , sizeof(g)) ; id = 1 ; } char str[28][28] ; int main(){ int n , m , x , d , i , j , t , T = 1 ; int u , v , w , a , b , sum ; cin>>t ; while(t--){ cin>>n>>d ; init() ; for(i = 1 ; i <= n ; i++) scanf("%s" , str[i] + 1) ; m = strlen(str[1]+1) ; sourse = 0 , meet = n*m*2 + 1 ; for(i = 1 ; i <= n ; i++){ for(j = 1 ; j <= m ; j++){ w = str[i][j] - '0' ; u = (i-1)*m + j ; add(u , u+n*m , w) ; } } for(i = 1 ; i <= n ; i++){ for(j = 1 ; j <= m ; j++){ if(str[i][j] == '0') continue ; for(a = 1 ; a <= n ; a++){ for(b = 1 ; b <= m ; b++){ if(str[a][b] == '0') continue ; if(i == a && j == b) continue ; if(abs(i - a) + abs(j - b) <= d){ u = (i-1)*m + j ; v = (a-1)*m + b ; add(u+n*m ,v , inf) ; add(v+n*m , u , inf) ; } } } } } for(i = 1 ; i <= n ; i++){ for(j = 1 ; j <= m ; j++){ if(str[i][j] == '0') continue ; if(i <= d || j <= d || i >= n-d+1 || j >= m-d+1){ u = (i-1)*m + j ; add(u+n*m , meet , inf) ; } } } sum = 0 ; for(i = 1 ; i <= n ; i++) scanf("%s" , str[i]+1) ; for(i = 1 ; i <= n ; i++){ for(j = 1 ; j <= m ; j++){ if(str[i][j] == 'L'){ sum++ ; u = (i-1)*m + j ; add(sourse , u , 1) ; } } } sum -= maxflow() ; printf("Case #%d: " , T++) ; if(sum == 0) printf("no lizard was left behind.\n") ; else if(sum == 1) printf("1 lizard was left behind.\n") ; else printf("%d lizards were left behind.\n" , sum) ; } return 0 ; }