Oakley

QQ:136808543

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

2709: [Violet 1]迷宫花园

Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 758  Solved: 264

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));
	}
}

阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Oakley_/article/details/52381382
个人分类: BZOJ 二分 最短路
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

不良信息举报

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

最多只允许输入30个字

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭