bzoj 1295: [SCOI2009]最长距离 暴力+bfs最短路

题目链接:

http://www.lydsy.com/JudgeOnline/problem.php?id=1295

题解:

对每个点暴力跑一遍bfs,看能够到达的最远位置,这里如果有障碍物则距离为1,如果没有障碍物,则距离为0,用bfs跑距离<=t的所有点并更新答案。

代码:

#include<iostream>
#include<cstring>
#include<cstdio>
#include<utility>
#include<queue>
#include<cmath>
using namespace std;

double get_dis(int x,int y,int a,int b){
    return sqrt(1.0*(x-a)*(x-a)+1.0*(y-b)*(y-b)); 
}

struct Node{
    int x,y,d;
    Node(int x,int y,int d):x(x),y(y),d(d){}
    Node(){}
    bool operator < (const Node& tmp) const{
        return d>tmp.d;
    }
};

const int maxn=33;

int mp[maxn][maxn];
int n,m,t;
char str[maxn];
double ans;

int d[maxn][maxn],vis[maxn][maxn];
const int dx[]={-1,1,0,0};
const int dy[]={0,0,-1,1};
void bfs(int sx,int sy,int t){
    if(mp[sx][sy]==1) t--;
    if(t<0) return;
    memset(d,0x7f,sizeof(d));
    memset(vis,0,sizeof(vis));
    priority_queue<Node> Q;
    Q.push(Node(sx,sy,0)),d[sx][sy]=0,vis[sx][sy]=1;
    while(!Q.empty()){
        int x=Q.top().x,y=Q.top().y;
        ans=max(ans,get_dis(sx,sy,x,y));
        Q.pop();
        for(int i=0;i<4;i++){
            int a=x+dx[i],b=y+dy[i];
            if(a<0||a>=n||b<0||b>=m) continue;
            if(vis[a][b]||mp[a][b]+d[x][y]>t) continue;
            d[a][b]=d[x][y]+mp[a][b],vis[a][b]=1,Q.push(Node(a,b,d[a][b]));
        }
    } 
}

int main(){
    while(scanf("%d%d%d",&n,&m,&t)==3){
        for(int i=0;i<n;i++){
            scanf("%s",str);
            for(int j=0;j<m;j++){
                mp[i][j]=str[j]-'0';
            }
        }
        ans=-1;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                bfs(i,j,t);
            }
        }
        printf("%.6lf
",ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/fenice/p/5554332.html