[bzoj1295][SCOI2009]最长距离

给定一个n*m的图,有些点有障碍物。你可以移开T个障碍物,求最远的两点距离。n,m<=30

题解:枚举一个点,spfa然后更新答案。

#include<iostream>
#include<cstdio>
#include<queue>
#include<cmath>
#include<cstring> 
#define MN 30
#define INF 200000000
using namespace std;
inline int read()
{
    int x = 0 , f = 1; char ch = getchar();
    while(ch < '0' || ch > '9'){ if(ch == '-') f = -1;  ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = x * 10 + ch - '0';ch = getchar();}
    return x * f;
}

int n,m,T,ans=0;
int d[MN+5][MN+5];
char s[MN+5][MN+5];
inline int sqr(int x){return x*x;}
struct P{int x,y;};queue<P> q;
const int dis[4][2]={{1,0},{-1,0},{0,1},{0,-1}};

void calc(int fx,int fy)
{
    memset(d,127,sizeof(d));d[fx][fy]=s[fx][fy]=='1';
    q.push((P){fx,fy});
    while(!q.empty())
    {
        P x=q.front();q.pop();
        for(int i=0;i<4;i++)
        {
            int xx=x.x+dis[i][0],yy=x.y+dis[i][1];
            if(s[xx][yy]!='1'&&s[xx][yy]!='0') continue;
            if(d[xx][yy]>d[x.x][x.y]+(s[xx][yy]=='1')) 
            {
                d[xx][yy]=d[x.x][x.y]+(s[xx][yy]=='1');
                q.push((P){xx,yy});
            }
        }
    }
}

int main()
{
    n=read();m=read();T=read();
    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++) 
        {
            calc(i,j);
            for(int k=1;k<=n;k++)
                for(int l=1;l<=m;l++)
                    if(d[k][l]<=T&&sqr(i-k)+sqr(j-l)>ans)
                        ans=sqr(i-k)+sqr(j-l);
        }
    printf("%0.6lf",(double)sqrt(ans));
    return 0;
}
原文地址:https://www.cnblogs.com/FallDream/p/bzoj1295.html