1. 程式人生 > >1295. [SCOI2009]最長距離【最短路】

1295. [SCOI2009]最長距離【最短路】

ace out 字符 spf 輸出 int con using content

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]最長距離【最短路】