码迷,mamicode.com
首页 > 其他好文 > 详细

1295. [SCOI2009]最长距离【最短路】

时间:2018-03-31 15:55:39      阅读:136      评论:0      收藏:0      [点我收藏+]

标签:rip   char s   false   bool   文件   ==   can   接下来   math   

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
 
连向空的边长为0,连向墙的边长为1
 
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define N (100+5)
#define id(x,y) (x-1)*m+y
using namespace std;
int n,m,t,a[N][N];
double ans;
int head[N*N],num_edge;
int dis[1001][1001];
bool used[N*N];
int dx[6]={0,1,-1,0,0},dy[6]={0,0,0,1,-1};
char st[N];
struct node
{
	int to,next,len;
}edge[N*N*N];
queue<int>q;

void add(int u,int v,int l)
{
	edge[++num_edge].to=v;
	edge[num_edge].next=head[u];
	edge[num_edge].len=l;
	head[u]=num_edge;
}

void Spfa(int x,int y)
{
	int s=id(x,y);
	dis[s][s]=0;
	used[s]=true;
	q.push(s);
	while (!q.empty())
	{
		int x=q.front(); q.pop();
		for (int i=head[x];i!=0;i=edge[i].next)
			if (dis[s][x]+edge[i].len<dis[s][edge[i].to])
			{
				dis[s][edge[i].to]=dis[s][x]+edge[i].len;
				if (!used[edge[i].to])
				{
					used[edge[i].to]=true;
					q.push(edge[i].to);
				}
			}
		used[x]=false;
	}
}

int main()
{
	scanf("%d%d%d",&n,&m,&t);
	for (int i=1;i<=n;++i)
	{
		scanf("%s",st);
		for (int j=1;j<=m;++j)
			a[i][j]=st[j-1]-‘0‘;
	}
	for (int i=1;i<=n;++i)
		for (int j=1;j<=m;++j)
			for (int k=1;k<=4;++k)
				if (i+dx[k]>=1 && i+dx[k]<=n && j+dy[k]>=1 && j+dy[k]<=m)
					add(id(i,j) , id(i+dx[k],j+dy[k]) , a[i+dx[k]][j+dy[k]]);

	memset(dis,0x7f,sizeof(dis));
	for (int i=1;i<=n;++i)
		for (int j=1;j<=m;++j)
			Spfa(i,j);
	for (int i=1;i<=n;++i)
		for (int j=1;j<=m;++j)
			for (int k=1;k<=n;++k)
				for (int l=1;l<=m;++l)
					if ( dis[id(i,j)][id(k,l)] + (a[i][j]==1)<=t )
						ans=max(ans,sqrt((i-k)*(i-k)+(j-l)*(j-l)));
	printf("%0.6lf",ans);
}

 

1295. [SCOI2009]最长距离【最短路】

标签:rip   char s   false   bool   文件   ==   can   接下来   math   

原文地址:https://www.cnblogs.com/refun/p/8682372.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!