【洛谷 4162】最长距离

题目描述

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
3 3 0
001
001
110
输出 #1
1.414214
输入 #2
4 3 0
001
001
011
000
输出 #2
3.605551
输入 #3
3 3 1
001
001
001

Sample Output
输出 #3
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 。

题解:最短路的应用,利用已给01图重新构图即可。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
typedef long long ll;
using namespace std;
int n,m,t;
double ans=-1.0;
char s[43][43];
int dx[6]={0,0,0,1,-1};
int dy[6]={0,1,-1,0,0};
double d[1010][1010],maxx;
int dis[1010],start[1010];
bool vis[1010];
struct node{
    int to,next,w;
}e[1333343];
int head[1010],k;
void adde(int u,int v,int w){ 
    e[++k].to=v; 
    e[k].w=w; 
    e[k].next=head[u]; 
    head[u]=k; 
}
int id(int x,int y) { return n*(x-1)+y; }//得到这个点的编号
void spfa(int s){
    queue<int> q;
    for(int i=1;i<=n*m;i++) dis[i]=0x3f3f3f3f,vis[i]=0;
    dis[s]=start[s]; vis[s]=1; q.push(s);
    while(!q.empty()){
        int u=q.front(); q.pop(); vis[u]=0;
        ans=max(ans,d[s][u]);
        for(int i=head[u];i;i=e[i].next){
            int v=e[i].to;
            if(dis[v]>dis[u]+e[i].w) {
                dis[v]=dis[u]+e[i].w;
                if(!vis[v] && dis[v]<=t) q.push(v),vis[v]=1;
            }
        }
    }
}
int main()
{
    freopen("4162.in","r",stdin);
    freopen("4162.out","w",stdout);
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++) 
        scanf("%s",s[i]+1);
    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++)
                    d[id(i,j)][id(k,l)]=sqrt((i-k)*(i-k)+(j-l)*(j-l));  
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(s[i][j]=='1') start[id(i,j)]=1;
            for(int k=1;k<=4;k++){
                int tx=i+dx[k],ty=j+dy[k];
                if(tx<1 || ty<1 || tx>n || ty>m) continue;
                int w=s[tx][ty]-'0';
                adde(id(i,j),id(tx,ty),w);
            }
        }
    }
    for(int i=1;i<=n*m;i++) spfa(i);
    printf("%.6f",ans);
    return 0;
}
原文地址:https://www.cnblogs.com/wuhu-JJJ/p/11773946.html