BZOJ2709: [Violet 1]迷宫花园 二分+Spfa

来源:互联网 发布:徐州网络电视直播 编辑:程序博客网 时间:2024/06/08 17:10

2709: [Violet 1]迷宫花园

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 758  Solved: 264
[Submit][Status][Discuss]

Description

Input

Output

Sample Input

2
2.5 4 5
#####
#S #
# E#
#####
21 13 12
############
#S## #E#
# ## # # #
# # # # #
### # # # #
# # # # #
# ## # # #
## # # # #
### # # # #
## # # # #
# ## # #
# # #
############

Sample Output

0.50000
0.21053

HINT

题解:

二分一下v,然后重新构图跑spfa,看在L内能不能从S跑到T

#include<cmath>#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<queue>using namespace std;const int M=100005;const int N=10005;const double inf=2e9;int T,n,m,tot,mp[105][105]; int from[M],nxt[M],lj[N],to[M],cnt;double w[M],tim;void add(int f,int t,double p){cnt++;from[cnt]=f;to[cnt]=t;nxt[cnt]=lj[f];lj[f]=cnt;w[cnt]=p;}void insert(int x,int y,double p){add(x,y,p),add(y,x,p);}int get(int x,int y){return (x-1)*m+y;}queue<int>Q;double d[N];bool inq[N];void Spfa(int s,int t){while(!Q.empty()) Q.pop();for(int i=1;i<=n*m;i++) d[i]=inf;d[s]=0;Q.push(s);while(!Q.empty()){int x=Q.front();Q.pop();inq[x]=false;for(int i=lj[x];i;i=nxt[i])if(d[to[i]]>d[x]+w[i]) {d[to[i]]=d[x]+w[i];if(!inq[to[i]]){Q.push(to[i]);inq[to[i]]=true;} } }}int main(){//freopen("Oakley.out","w",stdout);scanf("%d",&T);while(T--){scanf("%lf%d%d",&tim,&n,&m);char c;int s,t;for(int i=1;i<=n;i++){scanf("\n"); for(int j=1;j<=m;j++){    scanf("%c",&c);if(c=='S') s=get(i,j);if(c=='E') t=get(i,j);    if(c!='#') mp[i][j]=1;}}//for(int i=1;i<=n;i++){for(int j=1;j<=m;j++)cout<<mp[i][j];cout<<endl;}double l=0,r=10,mid;while(l<r-1e-8){mid=(l+r)/2;cnt=0;for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)if(mp[i][j]) {    if(i>=2&&mp[i-1][j]) insert(get(i-1,j),get(i,j),mid);    if(j>=2&&mp[i][j-1]) insert(get(i,j-1),get(i,j),1);}//for(int i=1;i<=cnt;i++) {cout<<"from="<<from[i]<<" to="<<to[i];printf(" w=%lf\n",w[i]);}Spfa(s,t);if(d[t]<=tim) l=mid;else r=mid;memset(lj,0,sizeof(lj));}printf("%.5lf\n",mid);memset(mp,0,sizeof(mp));}}

0 0