zoukankan      html  css  js  c++  java
  • [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;
    }
    
  • 相关阅读:
    边推改革边上“保险” 央行“双降”两大亮点带来哪些变化
    今天走势将冲高回落后重新回归下跌周期
    小心!资本正在流出中国:国际收支表里被遗漏的-2547亿美元
    价格改革确立时间表和路线图 六大重点领域破题
    避免在办公室体重上升的三大良策
    别再说自己有多忙
    沪指可能展开一波3个交易日的调整
    专车新政博弈 垄断行业改革样本
    JS和CS互访【后台前台代码调用JavaScript变量以及JavaScript调用代码变量】
    net9:图片文件转换成二进制流存入SQL数据库,以及从数据库中读取二进制流输出文件
  • 原文地址:https://www.cnblogs.com/LSlzf/p/11415319.html
Copyright © 2011-2022 走看看