1. 程式人生 > >[SCOI2009] 最長距離

[SCOI2009] 最長距離

greate 浮點 space def clu 輸入格式 mem esp ring

題目描述

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 。

Solution

數據範圍30,30,只有900個點,跑900次\(dijkstra\),復雜度\(n^2logn\),這裏跑的最短路跑的是一個點到另一個點所至少需要走的障礙數,貌似能過,再暴力枚舉兩個點\(n^2\)判斷能不能到達,就這樣了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cmath>
using namespace std;
struct node
{   
    int to,next,w;
}a[5010000];
typedef pair<int,int> pr;
priority_queue<pr,vector<pr>,greater<pr> >q;
int len,last[1010010],vis[1010],d[1001][1001],mp[1000][1000],n,m,t;
int ar[]={0,0,1,-1};
int br[]={1,-1,0,0};
void add(int a1,int a2,int a3)
{
    a[++len].to=a2;
    a[len].w=a3;
    a[len].next=last[a1];
    last[a1]=len;
}
int real(int x,int y)
{
    return (x-1)*m+y;
}
void dijkstra(int s)
{
    memset(vis,0,sizeof(vis));
    d[s][s]=0;q.push((pr){0,s});
    while(!q.empty())
    {
        int k=q.top().second;q.pop();
        if(vis[k]) continue;
        vis[k]=1;
        for(int i=last[k];i;i=a[i].next)
        {
            int to=a[i].to;
            if(d[s][to]>d[s][k]+a[i].w)
            {
                d[s][to]=d[s][k]+a[i].w;
                if(!vis[to])
                q.push((pr){d[s][to],to});
            }
        }
    }
}
double dis(int i,int j,int x,int y)
{
    return sqrt((i-x)*(i-x)+(j-y)*(j-y));
}
int main()
{
    char s[50];
    memset(d,0x3f,sizeof(d));
    cin>>n>>m>>t;
    for(int i=1;i<=n;i++)
    {
        scanf("%s",s+1);
        for(int j=1;j<=m;j++)
        if(s[j]=='1') mp[i][j]=1;
    }
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    {
        for(int k=0;k<=3;k++)
        {   
            int x=i+ar[k],y=j+br[k];
            if(x==0||y==0||x==n+1||y==m+1) continue;
            add(real(i,j),real(x,y),mp[x][y]);
        }
    }
    double ans=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    dijkstra(real(i,j));
//  cout<<d[8][1]<<endl;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
    for(int x=1;x<=n;x++)
    for(int y=1;y<=m;y++)
    {
        int p1=real(i,j),p2=real(x,y);
        if(mp[i][j]) continue;
        if(d[p1][p2]<=t)
        {
            double pp=dis(i,j,x,y);
            if(ans<pp)
            ans=pp;
        }
    }
    printf("%.6lf",ans);
}

博主蒟蒻,可以隨意轉載,但必須附上原文鏈接k-z-j。

[SCOI2009] 最長距離