• BZOJ 3007 解救小云公主 二分答案+对偶图


    题目大意:给定一个矩形和矩形内的一些点。求一条左下角到右上角的路径。使全部点到这条路径的最小距离最大

    最小距离最大。果断二分答案

    如今问题转化成了给定矩形中的一些圆形障碍物求左下角和右上角是否连通

    然后就是对偶图的问题了

    左下角和右上角连通等价于对偶图中左上两条边和右下两条边不连通

    因此将全部相交的圆之间连边,从左上两条边广搜就可以

    时间复杂度O(n^2log(min(r,l)/EPS))

    #include <cmath>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define M 3030
    #define S 0
    #define T (n+1)
    using namespace std;
    struct Point{
    	double x,y;
    	friend istream& operator >> (istream &_,Point &p)
    	{
    		scanf("%lf%lf",&p.x,&p.y);
    		return _;
    	}
    	friend double Distance(const Point &p1,const Point &p2)
    	{
    		return sqrt( (p1.x-p2.x)*(p1.x-p2.x) + (p1.y-p2.y)*(p1.y-p2.y) );
    	}
    }pos,points[M];
    struct abcd{
    	int to,next;
    }table[M*M];
    int head[M],tot;
    int n;
    double dis[M][M];
    void Initialize()
    {
    	memset(head,0,sizeof head);
    	tot=0;
    }
    void Add(int x,int y)
    {
    	table[++tot].to=y;
    	table[tot].next=head[x];
    	head[x]=tot;
    }
    bool BFS()
    {
    	static int q[M];
    	static bool v[M];
    	int i,r=0,h=0;
    	memset(v,0,sizeof v);
    	v[S]=true;q[++r]=S;
    	while(r!=h)
    	{
    		int x=q[++h];
    		for(i=head[x];i;i=table[i].next)
    			if(!v[table[i].to])
    			{
    				v[table[i].to]=true;
    				q[++r]=table[i].to;
    				if(table[i].to==T)
    					return true;
    			}
    	}
    	return false;
    }
    bool Judge(double r)
    {
    	int i,j;
    	Initialize();
    	for(i=1;i<=n;i++)
    	{
    		if( points[i].x-1<r || pos.y-points[i].y<r )
    			Add(S,i);
    		if( points[i].y-1<r || pos.x-points[i].x<r )
    			Add(i,T);
    	}
    	for(i=1;i<=n;i++)
    		for(j=1;j<i;j++)
    			if( dis[i][j]<2*r )
    				Add(i,j),Add(j,i);
    	return !BFS();
    }
    double Bisection()
    {
    	double l=0,r=min(pos.x-1,pos.y-1);
    	while(r-l>1e-4)
    	{
    		double mid=(l+r)/2.0;
    		if( Judge(mid) )
    			l=mid;
    		else
    			r=mid;
    	}
    	return (l+r)/2.0;
    }
    int main()
    {
    	int i,j;
    	cin>>n>>pos;
    	for(i=1;i<=n;i++)
    		cin>>points[i];
    	for(i=1;i<=n;i++)
    		for(j=1;j<i;j++)
    			dis[i][j]=Distance(points[i],points[j]);
    	printf("%.2lf
    ", Bisection() );
    }
    


  • 相关阅读:
    sql sever 的两种写法
    多站点IIS用户安全权限设置图解教程
    phpmyadmin“无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装。”报错解决办法
    天下无难事只怕有心人
    apache配置上传目录禁止运行php的方法
    C语言|博客作业03
    C语言|博客作业07
    C语言|博客作业05
    2019秋季第一周作业
    C语言|博客作业06
  • 原文地址:https://www.cnblogs.com/yutingliuyl/p/6858505.html
Copyright © 2020-2023  润新知