bzoj3018 [Usaco2012 Nov]Distant Pastures 最短路

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3018

3018: [Usaco2012 Nov]Distant Pastures

Time Limit: 5 Sec   Memory Limit: 128 MB
Submit: 120   Solved: 56
[ Submit][ Status][ Discuss]

Description

Farmer John's farm is made up of an N x N grid of pastures, where each pasture contains one of two different types of grass. To specify these two types of grass, we use the characters ( and ), so for example FJ's farm might look like the following grid:
(())
)()(
)(((
))))
When Bessie the cow travels around the farm, it takes her A units of time to move from a pasture to an adjacent pasture (one step north, south, east, or west) with the same grass type, or B units of time to move to an adjacent pasture with a different grass type. Whenever Bessie travels from one pasture to a distant pasture, she always uses a sequence of steps that takes the minimum amount of time. Please compute the greatest amount of time Bessie will ever need to take while traveling between some pair of pastures on the farm.
 
问题描述
给定一个n×n的一个网格,每个格子有一个字符,要么是’(‘,要么是’)’。每个格子和它的上下左右的四个格子相邻,对于相邻的两个格子xy,从x走到y的过程中,如果xy中的字符相同,消耗A单位时间,如果xy中字符不同,消耗B单位时间。定义点S到点T的时间为D(S,T),现在想请你求出网格中最大的D(S,T)。
 

Input

第一行三个整数nAB
接下来n行描述这个n×n的网格。
1 <= n <= 30,1 <= A <= 1,000,000,1 <= B <= 1,000,000。

Output

 
 一个整数,最大的D(S,T)。
 

Sample Input

3 1 2
(((
()(
(()

Sample Output

5
样例说明
左上角到右下角所需的时间为5,是最大值

HINT

这题其实就是裸最短路,就是比较难写,用dis[i][j][k][l]表示从(i,j)到(k,l)的最短距离,最后再求个max就可以了。

代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
int read()
{
	char c;int sum=0,f=1;c=getchar();
	while(c<'0' || c>'9'){if(c=='-')f=-1;c=getchar();}
	while(c>='0' && c<='9'){sum=sum*10+c-'0';c=getchar();}
	return sum*f;
}
int n,A,B;
int a[35][35];
char c;
LL dis[35][35][35][35],ans=-2;
bool vis[35][35];
struct node{
	int x,y;
};
int fx[4]={-1,1,0,0},fy[4]={0,0,-1,1};
bool check(int x,int y)
{
	if(x>=1 && x<=n && y>=1 && y<=n)
	return 1;
	return 0;
}
void spfa(int sx,int sy)
{
	memset(vis,0,sizeof(vis));
	queue<node> q;
	q.push((node){sx,sy});
	vis[sx][sy]=1;
	dis[sx][sy][sx][sy]=0;
	while(!q.empty())
	{
		node now=q.front();
		q.pop();
		vis[now.x][now.y]=0;
		for(int i=0;i<4;i++)
		{
			int nex=now.x+fx[i],ney=now.y+fy[i];
			if(check(nex,ney))
			{
				int ret;
				if(a[now.x][now.y]!=a[nex][ney])
				ret=B;
				if(a[now.x][now.y]==a[nex][ney])
				ret=A;
				if(dis[sx][sy][nex][ney]==-1 || dis[sx][sy][nex][ney]>dis[sx][sy][now.x][now.y]+ret)
				{
					dis[sx][sy][nex][ney]=dis[sx][sy][now.x][now.y]+ret;
					if(!vis[nex][ney])
					{
						vis[nex][ney]=1;
						q.push((node){nex,ney}); 
					}
				}
			}
		}
	}
}
int main()
{
	n=read();A=read();B=read();
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	{
		cin>>c;
		if(c=='(')
		a[i][j]=0;
		if(c==')')
		a[i][j]=1;
	}
	memset(dis,-1,sizeof(dis));
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	spfa(i,j);
	for(int i=1;i<=n;i++)
	for(int j=1;j<=n;j++)
	for(int k=1;k<=n;k++)
	for(int l=1;l<=n;l++)
	ans=max(ans,dis[i][j][k][l]);
	cout<<ans<<endl;
	return 0;
}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值