HDU-2732-Leapin' Lizards(最大流,拆点,Dinic,弧优化)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2732

Problem Description

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.

 

 

Input

The input file will begin with a line containing a single integer representing the number of test cases, which is at most 25. Each test case will begin with a line containing a single positive integer n representing the number of rows in the map, followed by a single non-negative integer d representing the maximum leaping distance for the lizards. Two maps will follow, each as a map of characters with one row per line. The first map will contain a digit (0-3) in each position representing the number of jumps the pillar in that position will sustain before collapsing (0 means there is no pillar there). The second map will follow, with an 'L' for every position where a lizard is on the pillar and a '.' for every empty pillar. There will never be a lizard on a position where there is no pillar.Each input map is guaranteed to be a rectangle of size n x m, where 1 ≤ n ≤ 20 and 1 ≤ m ≤ 20. The leaping distance is
always 1 ≤ d ≤ 3.

 

 

Output

For each input case, print a single line containing the number of lizards that could not escape. The format should follow the samples provided below.

 

Sample Input
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..
........
........
 

Sample Output
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.

题目大意:T组测试数据,每组测试数据输入 n(n行的地图)没有m,需要自己找,再给一个D,一只蜥蜴行走的最远距离, 再给出两个图,分别是某个位置所能行走的次数,后面的那个图是蜥蜴的初始位置,看蜥蜴们能不能逃出这个地图(出地图边界)

很明显的拆点,一个平台分成两半,自己与自己联通的是流量限制,与其他联通的是INF;

下面的图给的是与 源 的连线;

能直接跳出来的与 汇 直接连;

一般难度拆点题:我感觉用上弧优化会更快一点,但是看时间,似乎不用弧优化也可以过,但我没试

ac;

#include<stdio.h>
#include<string.h>  
#include<math.h>  
  
#include<map>   
//#include<set>
#include<deque>  
#include<queue>  
#include<stack>  
#include<bitset> 
#include<string>  
#include<fstream>
#include<iostream>  
#include<algorithm>  
using namespace std;  

#define ll long long  
#define INF 0x3f3f3f3f  
#define mod 998244353
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b) 
#define clean(a,b) memset(a,b,sizeof(a))// 水印 
//std::ios::sync_with_stdio(false);
struct dot{
	int x,y;
}d[100010];
struct node{
	int v,w,cost,nxt;
	node(int _v=0,int _w=0,int _nxt=0):
    v(_v),w(_w),nxt(_nxt){}
}edge[500005<<1];
int head[500005],cur[500005],ecnt;
int dis[500005];
int n,m,s,t;
int D,sum;
void intt()
{
	clean(head,-1);
	clean(cur,-1);
	ecnt=0;
	s=0,t=801;
}
void add(int u,int v,int w)
{
	edge[ecnt]=node(v,w,head[u]);
	head[u]=ecnt++;
	edge[ecnt]=node(u,0,head[v]);
	head[v]=ecnt++;
}
/*---上面的是板子,不用动---*/

bool bfs()
{
	clean(dis,-1);
	dis[s]=0;
	queue<int> que;
	que.push(s);
	while(que.size())
	{
		int u=que.front();
		que.pop();
		if(u==t)
			return 1; 
		for(int i=head[u];i+1;i=edge[i].nxt)
		{
			int temp=edge[i].v;
			if(dis[temp]==-1&&edge[i].w>0)
			{
				dis[temp]=dis[u]+1;
				que.push(temp);
			}
		}
	}
	return 0;
}

int dfs(int u,int low)
{
	if(u==t||low==0)
		return low;
	int res=0;
	for(int &i=cur[u];i+1;i=edge[i].nxt)
	{
		int temp=edge[i].v;
		if(dis[temp]==dis[u]+1&&edge[i].w>0)
		{
			int f=dfs(temp,min(low-res,edge[i].w));
			edge[i].w-=f;
			edge[i^1].w+=f;
			res=res+f;
			if(res==low)
				break;
		}
	}
	return res;
}

int dinic()
{
	int ans=0,res;
	while(bfs())
	{
		for(int i=s;i<=t;++i)
			cur[i]=head[i];
		ans=ans+dfs(s,INF);
	}
	return ans;
}

int main()
{
	int T,Cas=1;
	cin>>T;
	while(T--)
	{
		intt();
		cin>>n>>D;
		sum=0;
		string str;
		for(int i=1;i<=n;++i)//读入次数 
		{
			cin>>str;
			if(i==1)
				m=str.size();
			int len=m;
			for(int j=0;j<len;++j)
			{
				if(str[j]-'0'>0)
				{
					int u=(i-1)*m+j+1;
					add(u,u+400,str[j]-'0');//拆点 
					if(i-D<=0||i+D>n||j-D<0||j+D>=m)
						add(u+400,t,INF);//直接跳出地图 
					else
					{
						for(int k=1;k<=n;++k)
						{
							for(int h=0;h<m;++h)
							{
								int u2=(k-1)*m+h+1;
								if(u==u2)
									continue;
								if(abs(i-k)+abs(j-h)<=D)
									add(u+400,u2,INF);
							}
						}
					}
				}
			}
		}
		for(int i=1;i<=n;++i)//读入柱子 
		{
			cin>>str;
			for(int j=0;j<m;++j)
			{
				int u=(i-1)*m+j+1;
				if(str[j]=='L')
				{
					++sum;//加一只蜥蜴
					add(s,u,1);
				}
			}
		}
//		for(int i=s;i<=t;++i)//图没错 
//		{
//			cout<<i<<" : ";
//			for(int j=head[i];j+1;j=edge[j].nxt)
//				cout<<edge[j].v<<" "<<edge[j].w<<" ->>";
//			cout<<endl;
//		}
		
		int ans=sum-dinic();
		//cout<<ans<<" "<<sum-ans<<endl;
		if(ans==0)
			cout<<"Case #"<<Cas++<<": no lizard was left behind."<<endl;
		else if(ans==1)
			cout<<"Case #"<<Cas++<<": 1 lizard was left behind."<<endl;
		else
			cout<<"Case #"<<Cas++<<": "<<ans<<" lizards were left behind."<<endl;
	}
}

 

全部评论

相关推荐

避坑恶心到我了大家好,今天我想跟大家聊聊我在成都千子成智能科技有限公司(以下简称千子成)的求职经历,希望能给大家一些参考。千子成的母公司是“同创主悦”,主要经营各种产品,比如菜刀、POS机、电话卡等等。听起来是不是有点像地推销售公司?没错,就是那种类型的公司。我当时刚毕业,急需一份临时工作,所以在BOSS上看到了千子成的招聘信息。他们承诺无责底薪5000元,还包住宿,这吸引了我。面试的时候,HR也说了同样的话,感觉挺靠谱的。于是,我满怀期待地等待结果。结果出来后,我通过了面试,第二天就收到了试岗通知。试岗的内容就是地推销售,公司划定一个区域,然后你就得见人就问,问店铺、问路人,一直问到他们有意向为止。如果他们有兴趣,你就得摇同事帮忙推动,促进成交。说说一天的工作安排吧。工作时间是从早上8:30到晚上18:30。早上7点有人叫你起床,收拾后去公司,然后唱歌跳舞(销售公司都这样),7:55早课(类似宣誓),8:05同事间联系销售话术,8:15分享销售技巧,8:30经理训话。9:20左右从公司下市场,公交、地铁、自行车自费。到了市场大概10点左右,开始地推工作。中午吃饭时间大约是12:00,公司附近的路边盖饭面馆店自费AA,吃饭时间大约40分钟左右。吃完饭后继续地推工作,没有所谓的固定中午午休时间。下午6点下班后返回公司,不能直接下班,需要与同事交流话术,经理讲话洗脑。正常情况下9点下班。整个上班的一天中,早上到公司就是站着的,到晚上下班前都是站着。每天步数2万步以上。公司员工没有自己的工位,百来号人挤在一个20平方米的空间里听经理洗脑。白天就在市场上奔波,公司的投入成本几乎只有租金和工资,没有中央空调。早上2小时,晚上加班2小时,纯蒸桑拿。没有任何福利,节假日也没有3倍工资之类的。偶尔会有冲的酸梅汤和西瓜什么的。公司的晋升路径也很有意思:新人—组长—领队—主管—副经理—经理。要求是业绩和团队人数,类似传销模式,把人留下来。新人不能加微信、不能吐槽公司、不能有负面情绪、不能谈恋爱、不能说累。在公司没有任何坐的地方,不能依墙而坐。早上吃早饭在公司外面的安全通道,未到上班时间还会让你吃快些不能磨蹭。总之就是想榨干你。复试的时候,带你的师傅会给你营造一个钱多事少离家近的工作氛围,吹嘘工资有多高、还能吹自己毕业于好大学。然后让你早点来公司、无偿加班、抓住你可能不会走的心思进一步压榨你。总之,大家在找工作的时候一定要擦亮眼睛,避免踩坑!———来自网友
qq乃乃好喝到咩噗茶:不要做没有专业门槛的工作
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务