Time Limit: 1000 MS Memory Limit: 32768 KB
64-bit integer IO format: %I64d , %I64u Java class name: Main
[Submit] [Status] [Discuss]
Your platoon of wandering lizards has entered a strange room in the labyrinth you are exploring. As you are looking around for hidden treasures, one of the rookies steps on an innocent-looking stone and the room's floor suddenly disappears! Each lizard in your platoon is left standing on a fragile-looking pillar, and a fire begins to rage below... Leave no lizard behind! Get as many lizards as possible out of the room, and report the number of casualties.
The pillars in the room are aligned as a grid, with each pillar one unit away from the pillars to its east, west, north and south. Pillars at the edge of the grid are one unit away from the edge of the room (safety). Not all pillars necessarily have a lizard. A lizard is able to leap onto any unoccupied pillar that is within d units of his current one. A lizard standing on a pillar within leaping distance of the edge of the room may always leap to safety... but there's a catch: each pillar becomes weakened after each jump, and will soon collapse and no longer be usable by other lizards. Leaping onto a pillar does not cause it to weaken or collapse; only leaping off of it causes it to weaken and eventually collapse. Only one lizard may be on a pillar at any given time.
4 3 1 1111 1111 1111 LLLL LLLL LLLL 3 2 00000 01110 00000 ..... .LLL. ..... 3 1 00000 01110 00000 ..... .LLL. ..... 5 2 00000000 02000000 00321100 02000000 00000000 ........ ........ ..LLLL.. ........ ........
Case #1: 2 lizards were left behind. Case #2: no lizard was left behind. Case #3: 3 lizards were left behind. Case #4: 1 lizard was left behind.
题意:给你n行,列不定的矩阵。里面有若干蜥蜴,给你蜥蜴跳一次的最大距离,告诉你每个位置最多能跳多少次,问有多少只蜥蜴跳不出来(跳的方式最优)。
思路:构好图就可以用最大流求解了,对于图上的每个点都设置两个节点,形成 源点-——>Ai——>Bi——>汇点。对于图上每个点,若有蜥蜴,则在源点至这个Ai点上加一条容量为1的边;每个点自身到自身有一条容量为跳的次数的边(即Ak至Bk);若能通过跳跃从i点跳到j点,则在Bi至Aj上加一条容量为跳的次数的边;最后能到达图外的i点,从Bi到汇点加一条容量为跳的次数的边。然后跑一边最大流就行。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
const int MAXN = 3000;
const int inf = 2147483647;
struct edge{
int to,cap,rev;
edge(int a=0,int b=0,int c=0) :to(a),cap(b),rev(c){}
};
int map1[30][30];
int map2[30][30];
bool map3[30][30];
vector G[MAXN];
bool used[MAXN];
int iter[MAXN];
int level[MAXN];
int hang,tiao,len;
int step1[4] = {1,-1,0, 0};
int step2[4] = {0, 0,1,-1};
void Add(int f,int t,int c)
{
G[f].push_back(edge{t,c,G[t].size()} );
G[t].push_back(edge{f,0,G[f].size()-1} );
}
void init()
{
for(int i = 0;i < MAXN;i++){
G[i].clear();
}
memset(map1,0,sizeof(map1));
memset(map2,0,sizeof(map2));
memset(map3,false,sizeof(map3));
}
void bfs(int s)
{
memset(level,-1,sizeof(level));
queue que;
que.push(s);
level[s] = 0;
while(!que.empty()){
int v = que.front();
que.pop();
for(int i = 0;i < G[v].size();i++){
edge &e = G[v][i];
if(e.cap > 0 && level[e.to] == -1){
level[e.to] = level[v]+1;
que.push(e.to);
}
}
}
}
int dfs2(int v,int t,int f)
{
if(v == t) return f;
for(int &i = iter[v];i < G[v].size();i++){
edge &e = G[v][i];
if(e.cap > 0 && level[v] < level[e.to]){
int d = dfs2(e.to,t,min(f,e.cap));
if(d > 0) {
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
}
return 0;
}
int MAX2(int s,int t)
{
int f = 0;
while(true){
bfs(s);
if(level[t] < 0) return f;
memset(iter,0,sizeof(iter));
int tempf;
while(tempf = dfs2(s,t,inf) > 0) f += tempf;
}
}
int zdian(int h,int l)
{
return (h-1)*len+l;
}
int ABS(int a)
{
if(a > 0)
return a;
else
return (-a);
}
int main()
{
int t;int Case = 1;
while(scanf("%d",&t) != EOF){
while(t--){
init();
char name[30];
len = -1;
int yuan = 0,hui = 0;
int xiyisum = 0;
int diansum = 0;
scanf("%d%d",&hang,&tiao);
for(int i = 1;i <= hang;i++){
scanf("%s",name);
if(len == -1) len = strlen(name);
for(int j = 1;j <= len;j++){
map1[i][j] = name[j-1]-'0';
}
}
memset(map2,-1,sizeof(map2));
for(int i = 1;i <= hang;i++){
scanf("%s",name);
for(int j = 1;j <= len;j++){
if(name[j-1] == 'L'){
xiyisum++;
map2[i][j] = 1;
}
}
}
diansum = len*hang;
int tx,ty,td1,td2;
hui = 2*diansum+1;
for(int i = 1;i <= hang;i++){//给格子加边
for(int j = 1;j <= len;j++){
if(map1[i][j] == 0){
continue;
}
td1 = zdian(i,j);
Add(td1,diansum+td1,map1[i][j]);
for(int p1 = i-tiao;p1 <= i+tiao;p1++)
for(int p2 = j-tiao;p2 <= j+tiao;p2++){
if( (ABS(p1-i)+ABS(p2-j)) > tiao){
continue;
}
if(i == p1 && j == p2) continue;
tx = p1;
ty = p2;
td2 = zdian(tx,ty);
if(tx >= 1 && tx <= hang && ty >= 1 && ty <= len){
if(map1[tx][ty] > 0){
Add(diansum+td1,td2,map1[i][j]);
}
}
else{
if(map3[i][j] == false){
map3[i][j] = true;
Add(diansum+td1,hui,map1[i][j]);
}
}
}
}
}
for(int i = 1;i <= hang;i++){//给蜥蜴加边
for(int j = 1;j <= len;j++){
if(map2[i][j] != 1) continue;
td1 = zdian(i,j);
Add(yuan,td1,1);
}
}
int ans = MAX2(yuan,hui);
if(ans != xiyisum){
if(xiyisum-ans == 1){
printf("Case #%d: %d lizard was left behind.\n",Case++,xiyisum-ans);
}
else{
printf("Case #%d: %d lizards were left behind.\n",Case++,xiyisum-ans);
}
}
else{
printf("Case #%d: no lizard was left behind.\n",Case++);
}
}
}
return 0;
}