题意:一个矩阵,起点终点固定,有障碍,横向相邻两格的时间固定为1,要求纵向的时间,然后给定L,要求从起点到终点在<=L的情况下尽量大。
这煞笔二分题啊,还不卡精度简直良心啊,然后我因为没写head[x]=tot而调了半个小时。。???没脸见人了┴─┴︵╰(‵□′╰)。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#define fo(i,a,b) for(int i=a;i<=b;i++)
#define fd(i,a,b) for(int i=a;i>=b;i--)
using namespace std;
const int N=1e5+5;
typedef long long ll;
typedef double db;
const db eps=1e-7;
db L;
queue<int>q;
int n,m,s,t;
int tot,head[N],next[N],go[N];
db val[N],dis[N];
int bz[N],vis[N];
char ch[105][105];
inline void add(int x,int y,db z,int w)
{
go[++tot]=y;
next[tot]=head[x];
val[tot]=z;
bz[tot]=w;
head[x]=tot;
}
inline db spfa(int s,int t)
{
memset(dis,127,sizeof(dis));dis[s]=0;
memset(vis,0,sizeof(vis));vis[s]=1;
q.push(s);
while (!q.empty())
{
int x=q.front();
q.pop();
for(int i=head[x];i;i=next[i])
{
int v=go[i];
if (dis[v]>dis[x]+val[i])
{
dis[v]=dis[x]+val[i];
if (!vis[v])
{
q.push(v);
vis[v]=1;
}
}
}
vis[x]=0;
}
return dis[t];
}
inline db pd(db x)
{
fo(i,1,tot)if (bz[i])val[i]=x;
return spfa(s,t);
}
int main()
{
int cas;
scanf("%d",&cas);
while (cas--)
{
L=tot=s=t=0;
memset(head,0,sizeof(head));
memset(ch,0,sizeof(ch));
scanf("%lf",&L);
scanf("%d%d\n",&n,&m);
fo(i,1,n)
{
gets(ch[i]+1);
fo(j,1,m)
if (ch[i][j]=='S')s=(i-1)*m+j;
else if (ch[i][j]=='E')t=(i-1)*m+j;
}
fo(i,1,n-1)
fo(j,1,m-1)
if (ch[i][j]=='S'||ch[i][j]=='E'||ch[i][j]==' ')
{
int x=(i-1)*m+j;
if (ch[i][j+1]=='S'||ch[i][j+1]=='E'||ch[i][j+1]==' ')
{
add(x,x+1,1,0);
add(x+1,x,1,0);
}
if (ch[i+1][j]=='S'||ch[i+1][j]=='E'||ch[i+1][j]==' ')
{
add(x,x+m,0,1);
add(x+m,x,0,1);
}
}
db l=0,r=10,ans=0.0;
while (r-l>eps)
{
db mid=(l+r)/2;
db dis=pd(mid);
if (dis<L)ans=l=mid;
else r=mid;
}
printf("%.5lf\n",ans);
}
}