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\n",ans);
    }
    return 0;
}
时间: 2024-10-15 03:09:21

bzoj 1295: [SCOI2009]最长距离 暴力+bfs最短路的相关文章

[BZOJ 1295][SCOI2009]最长距离(SPFA+暴力)

题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1295 分析:很巧妙的一道spfa从搜索的角度是搜索在所有1中搜索删除哪T个1,对整个图询问,这样肯定TLE 不妨反过来想一想:对于两个点,弄出联通这两个点所需删除的最少的1,那么就知道这两个点是否可以作为题目要求的起点和终点,如果满足算一下结果和ans比较一下就可以. 所以算法就出来了: 枚举起点(S,T),用SPFA跑出图上的所有点到起点这条路径联通的最少删除的1,那么ans=max(di

BZOJ 1295 SCOI2009 最长距离 SPFA+暴力

题目大意:给定一个棋盘,一些格子上有障碍物,可以移除T个障碍物,求移除后所有能互相到达的点对中的最大欧几里得距离 m,n<=30,900个点,我们可以枚举起始点,跑一遍SPFA,求出所有经过不超过T个障碍物可达的点,统计ans即可 #include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 40 usi

bzoj 1295: [SCOI2009]最长距离

1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstring> 5 using namespace std; 6 int n,m,T; 7 double ans=0; 8 bool mp[31][31],inq[31][31],vis[31][31]; 9 int dis[31][31]; 10 int dx[4]={1,-1,0,0}; 11 int dy[4]={

1295: [SCOI2009]最长距离

1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 960  Solved: 498[Submit][Status][Discuss] Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格子A不可以走到格子B,就没有距离. 如果格子X和格子Y有公共边,并且X和Y均不

【BZOJ 1295】 [SCOI2009]最长距离

1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 945  Solved: 492 [Submit][Status][Discuss] Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格子A不可以走到格子B,就没有距离. 如果格子X和格子Y有公共边,并且X和Y

(SPFA) bzoj 1295

1295: [SCOI2009]最长距离 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 922  Solved: 478[Submit][Status] Description windy有一块矩形土地,被分为 N*M 块 1*1 的小格子. 有的格子含有障碍物. 如果从格子A可以走到格子B,那么两个格子的距离就为两个格子中心的欧几里德距离. 如果从格子A不可以走到格子B,就没有距离. 如果格子X和格子Y有公共边,并且X和Y均不含有障碍物,就可以

矩阵乘法专题1——bzoj 1297 [SCOI2009] 迷路题解

题目链接 题意:给两个长度分别为n和m的序列,现在有两种操作:1.分别选择两个序列的一个非空前缀,切两个前缀的最后一位相同,删除之,得到1分(只累计),消耗e:2.直接删除两个序列,消耗值定于两个序列之前删除的元素个数之和,并且使得得到的分有效(之前没有有效分) 分析: 首先,问题其实就是转化成,进行若干次操作1,然后进行操作2 还要找到一个判别标准,来评判较优的状态(贪心) 每次的消耗值比较大,其实可以计算出最大的删除次数,这个值不是很大 状态表示: 简单的,一个状态可以表示为串A的位置.串B

BZOJ 1296: [SCOI2009]粉刷匠

BZOJ 1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷. Input 输入文件paint.in第一行包含三个整数,N M T. 接下来有N行,每行一个长度为M的字符串,

【暴力+BFS】HDU 4474 Yet Another Multiple Problem

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4474 题意:给出n和m个数位,求一个数X,这个数是n的最小倍数且他的每一位都不含有m个数位中的任意一个. 思路:反过来想,其实就是有非M的元素组成一个数,这个数是N的倍数.如果存在解,那么他的第一位便是非M组合中的任意一位,然后除N后,他的余数便是X-a*n,那么下一位除N的就是(X-a*n)*10+(枚举的下一个非M元素),要求最小这个数,那么BFS跑最短就可以了. 代码:https://github