好傻逼呀,二分+spfa,没了。
结果数据坑爹,有一行最后有一个空格,坑死了。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#define maxn 210
#define eps 1e-7
#define inf 1000000000
using namespace std;
double dis[40010];
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int a[maxn][maxn];
bool vis[40010];
int next[200010],to[200010],head[40010],q[40010];
double len[200010];
int num,n,m,cnt,s,t,T;
double L;
void addedge(int x,int y,double z)
{
num++;to[num]=y;len[num]=z;next[num]=head[x];head[x]=num;
}
double calc(double x)
{
memset(head,0,sizeof(head));
num=0;
for (int i=1;i<=n;i++)
for (int j=1;j<=m;j++)
if (a[i][j])
{
for (int k=0;k<2;k++)
if (a[i+dx[k]][j+dy[k]]) addedge(a[i][j],a[i+dx[k]][j+dy[k]],1);
for (int k=2;k<4;k++)
if (a[i+dx[k]][j+dy[k]]) addedge(a[i][j],a[i+dx[k]][j+dy[k]],x);
}
memset(vis,0,sizeof(vis));
for (int i=1;i<=cnt;i++) dis[i]=inf;
int l=0,r=1;
q[1]=s;vis[s]=1;dis[s]=0;
while (l!=r)
{
l++;if (l==40000) l=0;
int x=q[l];
for (int p=head[x];p;p=next[p])
if (dis[x]+len[p]<dis[to[p]])
{
dis[to[p]]=dis[x]+len[p];
if (!vis[to[p]])
{
r++;if (r==40000) r=0;
q[r]=to[p];vis[to[p]]=1;
}
}
vis[x]=0;
}
return dis[t];
}
int main()
{
scanf("%d",&T);
while (T--)
{
scanf("%lf%d%d",&L,&n,&m);
memset(a,0,sizeof(a));
cnt=0;
for (int i=1;i<=n;i++)
{
char c;
scanf("%c",&c);
while (c!='\n') scanf("%c",&c);
for (int j=0;j<m;j++)
{
scanf("%c",&c);
while (c=='\n') scanf("%c",&c);
if (c==' ') a[i][j+1]=++cnt;
if (c=='S') a[i][j+1]=++cnt,s=cnt;
if (c=='E') a[i][j+1]=++cnt,t=cnt;
}
}
double l=0,r=11,ans=0;
while ((r-l)>eps)
{
double mid=(l+r)/2.0;
if (calc(mid)>=L) ans=mid,r=mid; else l=mid;
}
printf("%.5lf\n",ans);
}
return 0;
}