【BZOJ 1295】 [SCOI2009]最长距离

1295: [SCOI2009]最长距离

Time Limit: 10 Sec  Memory Limit: 162 MB

Submit: 945  Solved: 492

[Submit][Status][Discuss]

Description

windy有一块矩形土地,被分为 N*M 块 1*1 的小格子。 有的格子含有障碍物。 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离。 如果从格子A不可以走到格子B,就没有距离。 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以从X走到Y。 如果windy可以移走T块障碍物,求所有格子间的最大距离。 保证移走T块障碍物以后,至少有一个格子不含有障碍物。

Input

输入文件maxlength.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,‘0‘表示空格子,‘1‘表示该格子含有障碍物。

Output

输出文件maxlength.out包含一个浮点数,保留6位小数。

Sample Input

【输入样例一】

3 3 0

001

001

110

【输入样例二】

4 3 0

001

001

011

000

【输入样例三】

3 3 1

001

001

001

Sample Output

【输出样例一】

1.414214

【输出样例二】

3.605551

【输出样例三】

2.828427

HINT

20%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 0 。

40%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 2 。

100%的数据,满足 1 <= N,M <= 30 ; 0 <= T <= 30 。

Source

Day2

spfa+暴力。

对于每一个格子,用spfa预处理出他到任何一个格子的至少要移除几个障碍。

然后暴力枚举需要移除障碍<=t的格子,输出最大距离。

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define M 900000+5
#define pa pair<int,int>
#define mp make_pair
#include <queue>
#define inf 0x3f3f3f3f
using namespace std;
struct data
{
	double dis;
	int need;
}r[M];
char s[100];
int f[5][3],tot=0,d[35][35],inq[35][35],n,m,t,a[35][35];
queue<pa> q;
double dis[35][35][35][35];
int C(int x,int y)
{
	return (x-1)*m+y;
}
bool ok(int x,int y)
{
	if (x<1||y<1||x>n||y>m) return false;
	return true;
}
void spfa(int x,int y)
{
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			d[i][j]=inf,inq[i][j]=0;
	d[x][y]=a[x][y];
	q.push(mp(x,y));
	inq[x][y]=1;
	while (!q.empty())
	{
		pa p=q.front();
		q.pop();
		int xx=p.first,yy=p.second;
		inq[xx][yy]=0;
		for (int i=1;i<=4;i++)
		{
			int nx=xx+f[i][1],ny=yy+f[i][2];
			if (ok(nx,ny)&&d[xx][yy]+a[nx][ny]<d[nx][ny])
			{
				d[nx][ny]=d[xx][yy]+a[nx][ny];
				if (!inq[nx][ny])
					inq[nx][ny]=1,q.push(mp(nx,ny));
			}
		}
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			r[++tot].dis=dis[i][j][x][y],r[tot].need=d[i][j];
}
bool cmp(data a,data b)
{
	return a.dis>b.dis;
}
int main()
{
	f[1][1]=f[2][1]=0,f[1][2]=1,f[2][2]=-1;
	f[3][2]=f[4][2]=0,f[3][1]=1,f[4][1]=-1;
	scanf("%d%d%d",&n,&m,&t);
	for (int i=1;i<=n;i++)
	{
		scanf("%s",1+s);
		for (int j=1;j<=m;j++)
			a[i][j]=s[j]-'0';
	}
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			for (int x=1;x<=n;x++)
				for (int y=1;y<=m;y++)
					dis[i][j][x][y]=sqrt((double)(x-i)*(x-i)+(y-j)*(y-j));
	for (int i=1;i<=n;i++)
		for (int j=1;j<=m;j++)
			spfa(i,j);
	sort(r+1,r+1+tot,cmp);
	for (int i=1;i<=tot;i++)
		if (r[i].need<=t)
		{
			printf("%.6lf\n",r[i].dis);
			return 0;
		}
	return 0;
}

时间: 2024-12-09 18:20:50

【BZOJ 1295】 [SCOI2009]最长距离的相关文章

[BZOJ 1295][SCOI2009]最长距离(SPFA+暴力)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295 分析:很巧妙的一道spfa从搜索的角度是搜索在所有1中搜索删除哪T个1,对整个图询问,这样肯定TLE 不妨反过来想一想:对于两个点,弄出联通这两个点所需删除的最少的1,那么就知道这两个点是否可以作为题目要求的起点和终点,如果满足算一下结果和ans比较一下就可以. 所以算法就出来了: 枚举起点(S,T),用SPFA跑出图上的所有点到起点这条路径联通的最少删除的1,那么ans=max(di

bzoj 1295: [SCOI2009]最长距离 暴力+bfs最短路

题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=1295 题解: 对每个点暴力跑一遍bfs,看能够到达的最远位置,这里如果有障碍物则距离为1,如果没有障碍物,则距离为0,用bfs跑距离<=t的所有点并更新答案. 代码: #include<iostream> #include<cstring> #include<cstdio> #include<utility> #include<queu

bzoj 1295: [SCOI2009]最长距离

1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 int n,m,T; 7 double ans=0; 8 bool mp[31][31],inq[31][31],vis[31][31]; 9 int dis[31][31]; 10 int dx[4]={1,-1,0,0}; 11 int dy[4]={

BZOJ 1295 SCOI2009 最长距离 SPFA+暴力

题目大意:给定一个棋盘,一些格子上有障碍物,可以移除T个障碍物,求移除后所有能互相到达的点对中的最大欧几里得距离 m,n<=30,900个点,我们可以枚举起始点,跑一遍SPFA,求出所有经过不超过T个障碍物可达的点,统计ans即可 #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 40 usi

1295: [SCOI2009]最长距离

1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 960  Solved: 498[Submit][Status][Discuss] Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格子A不可以走到格子B,就没有距离. 如果格子X和格子Y有公共边,并且X和Y均不

(SPFA) bzoj 1295

1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 922  Solved: 478[Submit][Status] Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格子A不可以走到格子B,就没有距离. 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以

矩阵乘法专题1——bzoj 1297 [SCOI2009] 迷路题解

题目链接 题意:给两个长度分别为n和m的序列,现在有两种操作:1.分别选择两个序列的一个非空前缀,切两个前缀的最后一位相同,删除之,得到1分(只累计),消耗e:2.直接删除两个序列,消耗值定于两个序列之前删除的元素个数之和,并且使得得到的分有效(之前没有有效分) 分析: 首先,问题其实就是转化成,进行若干次操作1,然后进行操作2 还要找到一个判别标准,来评判较优的状态(贪心) 每次的消耗值比较大,其实可以计算出最大的删除次数,这个值不是很大 状态表示: 简单的,一个状态可以表示为串A的位置.串B

BZOJ 1296: [SCOI2009]粉刷匠

BZOJ 1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷. Input 输入文件paint.in第一行包含三个整数,N M T. 接下来有N行,每行一个长度为M的字符串,

BZOJ 1295 最长距离

我还在纳闷怎么找最长的距离.... blutrex说枚举点对. .....我擦.... #include<iostream> #include<cstdio> #include<cstring> #include<queue> #include<cmath> #include<algorithm> #define maxv 905 #define maxe 180050 #define inf 0x7f7f7f7f using nam