• [BZOJ] 最长距离


    问题描述

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

    输入格式

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

    输出格式

    输出包含一个浮点数,保留 6 位小数。

    样例输入输出

    输入输出样例 1

    Input
    3 3 0
    001
    001
    110
    Output
    1.414214

    输入输出样例 2

    Input
    4 3 0
    001
    001
    011
    000
    Output
    3.605551

    输入输出样例 3

    Input
    3 3 1
    001
    001
    001
    Output
    2.828427

    数据范围

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

    解析

    可以发现,题目的重点在于最长的欧氏距离而不是删哪T个点,那么只要求出两个相距最远的点使其之间的路径最少经过的障碍点的数量小于T即可。接下来的问题是如何求出两点之间最少经过的障碍点。联想到最短路,对每个点跑一边Dijkstra即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <queue>
    #include <cstring>
    #include <cmath>
    #include <iomanip>
    #define N 32
    #define M 902
    using namespace std;
    int head[M],ver[M*4],nxt[M*4],edge[M*4],ll;
    int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    char c[N];
    int n,m,t,i,j,k,l,a[N][N],f[M][M];
    bool vis[M];
    void insert(int x,int y,int z)
    {
    	ll++;
    	ver[ll]=y;
    	edge[ll]=z;
    	nxt[ll]=head[x];
    	head[x]=ll;
    }
    bool in(int x,int y)
    {
    	return x<=n&&x>=1&&y<=m&&y>=1;
    }
    int get(int x,int y)
    {
    	return (x-1)*n+y;
    }
    void Dijkstra(int s)
    {
    	priority_queue<pair<int,int> > q;
    	memset(vis,0,sizeof(vis));
    	q.push(make_pair(0,s));
    	while(!q.empty()){
    		int x=q.top().second;
    		q.pop();
    		if(vis[x]) continue;
    		vis[x]=1;
    		for(int i=head[x];i;i=nxt[i]){
    			int y=ver[i];
    			if(f[s][y]>f[s][x]+edge[i]){
    				f[s][y]=f[s][x]+edge[i];
    				q.push(make_pair(-f[s][y],y));
    			}
    		}
    	}
    }
    double dis(int x1,int y1,int x2,int y2)
    {
    	return sqrt(1.0*(x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
    }
    int main()
    {
    	memset(f,0x3f,sizeof(f));
    	cin>>n>>m>>t;
    	for(i=1;i<=n;i++){
    		cin>>c;
    		for(j=0;j<m;j++) a[i][j+1]=c[j]-'0';
    	}
    	for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			for(k=0;k<4;k++){
    				int x=i+dx[k],y=j+dy[k];
    				if(in(x,y)) insert(get(i,j),get(x,y),a[x][y]);
    			}
    		}
    	}
    	for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			int x=get(i,j);
    			f[x][x]=a[i][j];
    			Dijkstra(x);
    		}
    	}
    	double ans=0;
    	for(i=1;i<=n;i++){
    		for(j=1;j<=m;j++){
    			for(k=1;k<=n;k++){
    				for(l=1;l<=m;l++){
    					int x=get(i,j),y=get(k,l);
    					if(x!=y&&f[x][y]<=t) ans=max(ans,dis(i,j,k,l));
    				}
    			}
    		}
    	}
    	cout<<setprecision(6)<<fixed<<ans<<endl;
    	return 0;
    }
    
  • 相关阅读:
    Java 连接 Memcached 服务
    Memcached命令-存储命令-查找命令-清理命令
    memcache安装
    Python爬虫模拟登录带验证码网站
    HashMap原理
    redis 在java中的使用
    redis 事务
    Redis命令续
    Redis命令
    ApplicationListener用法
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11415319.html
Copyright © 2020-2023  润新知