1295: [SCOI2009]最长距离
很暴力的一道题。
建图,每个点跑一遍spfa,然后能到的点距离取Max
一开始建图傻逼地把边建重了,又RE又WA。。。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
typedef long long LL;
const int maxn=35;
using namespace std;
int n,m,T,u,v,a[maxn*maxn],fir[4005],nxt[4005],to[4005],val[4005],ecnt,dis[1005],vis[1005];
char s[maxn];
double ans;
void add(int x,int y) {
nxt[++ecnt]=fir[x]; fir[x]=ecnt; to[ecnt]=y; val[ecnt]=a[y];
nxt[++ecnt]=fir[y]; fir[y]=ecnt; to[ecnt]=x; val[ecnt]=a[x];
}
int ok(int x,int y) {
v=(x-1)*m+y;
return x>=1&&x<=n&&y>=1&&y<=m;
}
double cal(int x,int y,int x2,int y2) {
return sqrt((double)(x-x2)*(x-x2)+(double)(y-y2)*(y-y2));
}
void spfa(int s_x,int s_y) {
int s=(s_x-1)*m+s_y;
queue<int>que;
memset(dis,127/3,sizeof(dis));
memset(vis,0,sizeof(vis));
dis[s]=a[s]; vis[s]=1;
que.push(s);
while(!que.empty()) {
int x=que.front();
que.pop();
vis[x]=0;
for(int i=fir[x];i;i=nxt[i]) {
if(dis[to[i]]>dis[x]+val[i]) {
dis[to[i]]=dis[x]+val[i];
if(!vis[to[i]]) {
vis[to[i]]=1;
que.push(to[i]);
}
}
}
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
if(dis[(i-1)*m+j]<=T)
ans=max(ans,cal(i,j,s_x,s_y));
}
}
int main()
{
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
scanf("%d%d%d",&n,&m,&T);
for(int i=1;i<=n;i++) {
scanf("%s",s+1);
for(int j=1;j<=m;j++) a[(i-1)*m+j]=s[j]-'0';
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
u=(i-1)*m+j;
//if(ok(i-1,j)) add(u,v);
if(ok(i+1,j)) add(u,v);
if(ok(i,j+1)) add(u,v);
//if(ok(i,j-1)) add(u,v);
}
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
spfa(i,j);
printf("%.6lf\n",ans);
return 0;
}