【BZOJ 1295】 [SCOI2009]最长距离
【链接】 我是链接,点我呀:)
【题意】
【题解】
转化一下思路。 我们求出任意两个点之间到达 最少经过的障碍物的个数。最后求出障碍物个数小于等于T的 枚举答案就好。
(任意两点间最少障碍物可以用一个类似spfa的方法求得
(很巧妙的转换
【代码】
#include <bits/stdc++.h>
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define all(x) x.begin(),x.end()
#define pb push_back
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
using namespace std;
const double pi = acos(-1);
const int dx[4] = {0,0,1,-1};
const int dy[4] = {1,-1,0,0};
const int N = 30;
int n,m,t,dis[N*N+10][N*N+10];;
vector<pair<int,int> > g[N*N+10];
char s[N+10][N+10];
queue<int> dl;
bool inq[N*N+10];
void deal_with(int x,int y){
memset(inq,0,sizeof inq);
int S = (x-1)*m+y;
memset(dis[S],255,sizeof dis[S]);
dis[S][S] = s[x][y]-'0';
dl.push(S);
inq[S] = true;
while (!dl.empty()){
int x = dl.front();dl.pop();
inq[x] = false;
for (int i = 0;i < (int)g[x].size();i++){
int y = g[x][i].first,cost = g[x][i].second;
if (dis[S][y]==-1 || dis[S][y]>dis[S][x]+cost) {
dis[S][y] = dis[S][x]+cost;
if (!inq[y]){
inq[y] = true;
dl.push(y);
}
}
}
}
}
double sqr(double x){
return x*x;
}
int main(){
#ifdef LOCAL_DEFINE
freopen("rush_in.txt", "r", stdin);
#endif
ios::sync_with_stdio(0),cin.tie(0);
cin >> n >> m >> t;
rep1(i,1,n) cin >> (s[i]+1);
rep1(i,1,n)
rep1(j,1,m)
rep1(k,0,3){
int tx = i + dx[k],ty = j+dy[k];
if (tx>=1 && tx<= n && ty>=1 && ty<=m){
int x = (i-1)*m+j,y = (tx-1)*m+ty;
g[x].push_back(make_pair(y,s[tx][ty]-'0'));
}
}
rep1(i,1,n)
rep1(j,1,m)
deal_with(i,j);
double ans = 0;
rep1(i,1,n)
rep1(j,1,m)
rep1(ii,1,n)
rep1(jj,1,m){
int x = (i-1)*m+j,y = (ii-1)*m+jj;
if (dis[x][y]<=t){
ans = max(ans,sqrt(sqr(ii-i)+sqr(jj-j)));
}
}
cout<<fixed<<setprecision(6)<<ans<<endl;
return 0;
}