每个格子只能走有限次 求有多少人可以走出方格 每个人一次最多移动d格
2018-03-30 19:09
423 查看
#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); } }
相关文章推荐
- 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
- 关于100根香蕉,猴子要背回50米远的家,一次最多只能背50根香蕉,但猴子每走1米后就要吃1根香蕉,问猴子最多可以背多少根香蕉回家?
- Codeforces Beta Round #69 (Div. 2 Only) E树型DP 一树,每个结点有虫子,一次只能吃一只,不能停留,问从根结点出发再回到根结点最多能吃多少只虫子
- 二货小易有一个W*H的网格盒子,网格的行编号为0~H-1,网格的列编号为0~W-1。每个格子至多可以放一块蛋糕,任意两块蛋糕的欧几里得距离不能等于2。 对于两个格子坐标(x1,y1),(x2,y2)的欧几里得距离为: ( (x1-x2) * (x1-x2) + (y1-y2) * (y1-y2) ) 的算术平方根 小易想知道最多可以放多少块蛋糕在网格盒子里。 输入描述: 每组数组包含网格长宽W,
- 现有一个m * n的网格,从最左上角出发,每次只能向右或者向下移动一格,问有多少种不同的方法可以到达最右下角的格子
- 在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会
- 在8X8的棋盘上分布着n个骑士,他们想约在某一个格中聚会。骑士每天可以像国际象棋中的马那样移动一次,可以从中间像8个方向移动(当然不能走出棋盘),请计算n个骑士的最早聚会地点和要走多少天。要求尽早聚会
- 第五题:n 只奶牛坐在一排,每个奶牛拥有 ai 个苹果,现在你要在它们之间转移苹果,使得最后所有奶牛拥有的苹果数都相同,每一次,你只能从一只奶牛身上拿走恰好两个苹果到另一个奶牛上,问最少需要移动多少次可以平分苹果,如果方案不存在输出 -1
- 第一讲 01背包问题——这是最基本的背包问题,每个物品最多只能放一次
- 网格中移动字母 2x3=6个方格中放入ABCDE五个字母,右下角的那个格空着。如图【1.jpg】所示。 和空格子相邻的格子中的字母可以移动到空格中,比如,图中的C和E就可以移动,移动后
- 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格
- 给定一个M*N的格子或棋盘,从左下角走到右上角的走法总数(每次只能向右或向上移动一个方格边长的距离)
- 牛客网 小东所在公司要发年终奖,而小东恰好获得了最高福利,他要在公司年会上参与一个抽奖游游戏在一个6*6的棋盘上进行,上面放着36个价值不等的礼物,每个小的棋盘上面放置着一个礼物,他需要从左上角开始游戏,每次只能向下或者向右移动一步,到达右下角停止,一路上的格子里的礼物小东都能拿到,请设计一个算法使小东拿到价值最高的礼物
- 地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。
- 独木舟上的旅行 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 进行一次独木舟的旅行活动,独木舟可以在港口租到,并且之间没有区别。一条独木舟最多只能乘坐两个人,且乘客的总
- 9.9递归和动态规划(二)——有个机器人坐在X*Y网格的左上角,只能向右、向下移动,机器人从(0,0)到(X,Y)有多少种走法
- 现在有一个城市销售经理,需要从公司出发,去拜访市内的商家,已知他的位置以及商家的位置,但是由于城市道路交通的原因,他只能在左右中选择一个方向,在上下中选择一个方向,现在问他有多少种方案到达商家地址。给定一个地图map及它的长宽n和m,其中1代表经理位置,2代表商家位置,-1代表不能经过的地区,0代表可以经过的地区,请返回方案数,保证一定存在合法路径。保证矩阵的长宽都小于等于10。
- 一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有 多少总跳法
- 将1,2,3,4,5,6,7,8,9九个数字分成以下三种形式之一,每个数字只能用一次,使得该分数刚好为一个整数
- java实现一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。