每個格子只能走有限次 求有多少人可以走出方格 每個人一次最多移動d格
阿新 • • 發佈:2019-01-28
#include<cstdio> #include<cstring> #include<queue> #include<cmath> using namespace std; const int maxn = 1200; const int INF = 0x3f3f3f3f; struct{ int to,next,flow; }e[maxn * maxn]; int S,T; int head[maxn],cnt,d[maxn]; void add_edge(int from,int to,int flow){ e[cnt].to = to; e[cnt].flow = flow; e[cnt].next = head[from]; head[from] = cnt++; e[cnt].to = from; e[cnt].flow = 0; e[cnt].next = head[to]; head[to] = cnt++; } int bfs(){ memset(d,0,sizeof(d)); queue<int>q; q.push(S); d[S] = 1; while(!q.empty()){ int u = q.front(); q.pop(); for( int i = head[u]; i != -1; i = e[i].next){ int v = e[i].to; if((!d[v]) && e[i].flow){ d[v] = d[u] + 1; if(v == T) return 1; q.push(v); } } } return 0; } int dfs(int u, int flow){ int cost = 0; if(u == T) return flow; for( int i = head[u]; i != -1; i = e[i].next){ int v = e[i].to; if(d[v] == d[u] + 1 && e[i].flow){ int t = dfs(v,min(flow - cost, e[i].flow)); if(t){ e[i].flow -= t; e[i^1].flow += t; cost += t; if(flow == cost) break; } } } return cost; } int Dinic(){ int res = 0; while(bfs()){ res += dfs(S,INF); } return res; } char s1[1200][1200],s2[1200][1200]; int main(){ int T1,t1 = 1,n,d1; scanf("%d",&T1); while(T1--){ cnt = 0; memset(head,-1,sizeof(head)); scanf("%d%d",&n,&d1); for( int i = 1; i <= n; i++) scanf("%s",s1[i]+1); for( int i = 1; i <= n; i++) scanf("%s",s2[i]+1); int m = strlen(s1[1] + 1); S = 2*n*m+1; T = 2 * n * m + 2; // printf("1------------\n"); for(int i = 1; i <= n; i++){ for( int j = 1; j <= m; j++){ if(s1[i][j] - '0'){ add_edge((i - 1) * m + j,(i - 1) * m + j + n * m,s1[i][j] - '0'); // printf("%d %d %d\n",(i - 1) * m + j,(i - 1) * m + j + n * m,s1[i][j] - '0'); } } } int res = 0; // printf("2------------\n"); for( int i = 1; i <= n; i++){ for( int j = 1; j <= m; j++){ if(s2[i][j] == 'L'){ res++; add_edge(S,(i - 1) * m + j,1); // printf("%d %d\n",S,(i-1)*m+j); } } } // printf("3------------\n"); for( int i = 1; i <= n; i++){ for(int j = 1; j <= m; j++){ if(i <= d1 || j <= d1 || j > m - d1 || i > n - d1){ add_edge( (i - 1) * m + j + n * m, T, INF); // printf("%d %d %d\n",(i - 1) * m + j + n * m,T,INF); } } } // printf("4------------\n"); for (int i = 1;i <= n;++i) { for (int j = 1;j <= m;++j) { for (int l = 1;l <= n;++l) { for (int r = 1;r <= m;++r) { if (!(i==l && j==r) && abs(i-l) + abs(j-r) <= d1) { add_edge((i - 1) * m + j + n * m ,(l - 1) * m + r , INF); // printf("%d %d %d\n",(l - 1) * m + r,(i - 1) * m + j + n * m ,INF);} } } } } } printf("Case #%d: ",t1++); int ans = Dinic(); if (res == ans) printf("no lizard was left behind.\n"); if (ans + 1 == res) printf("1 lizard was left behind.\n"); if (ans + 1 < res) printf("%d lizards were left behind.\n",res - ans); } }