[BZOJ 1027][JSOI2007]合金（计算几何+Floyd最小环）

Description

Solution

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define eps 1e-8
#define INF 0x3f3f3f3f
using namespace std;
int m,n,dis[505][505];
struct dot
{
double x,y;
dot(double x=0,double y=0):x(x),y(y){}
}a[505],b[505];
typedef dot Vector;
Vector operator + (Vector v1,Vector v2)
{return Vector(v1.x+v2.x,v1.y+v2.y);}
Vector operator - (Vector v1,Vector v2)
{return Vector(v1.x-v2.x,v1.y-v2.y);}
int dcmp(double x)
{
if(fabs(x)<eps)return 0;
return x>0?1:-1;
}
bool operator == (dot p1,dot p2)
{return (dcmp(p1.x-p2.x)&&dcmp(p1.y-p2.y))==0;}
double cross(Vector v1,Vector v2)
{return v1.x*v2.y-v2.x*v1.y;}
bool judge(dot x,dot y,dot z)
{
if(x==y&&x==z)return true;
Vector v1=z-x,v2=y-x;
if(dcmp(cross(v1,v2))<0)return true;
if(dcmp(cross(v1,v2))==0&&dcmp(z.x-min(x.x,y.x))>=0&&dcmp(z.x-max(x.x,y.x))<=0&&dcmp(z.y-min(x.y,y.y))>=0&&dcmp(z.y-max(x.y,y.y))<=0)return true;
return false;
}
int main()
{
scanf("%d%d",&m,&n);
for(int i=1;i<=m;i++)
{
double x,y,z;
scanf("%lf%lf%lf",&x,&y,&z);
a[i]=dot(x,y);
}
for(int i=1;i<=n;i++)
{
double x,y,z;
scanf("%lf%lf%lf",&x,&y,&z);
b[i]=dot(x,y);
}
memset(dis,0x3f,sizeof(dis));
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
{
bool f=1;
for(int k=1;k<=n;k++)
if(!judge(a[i],a[j],b[k]))
{f=0;break;}
if(f)dis[i][j]=1;
}
for(int k=1;k<=m;k++)
{
for(int i=1;i<=m;i++)
for(int j=1;j<=m;j++)
{
if(dis[i][j]>dis[i][k]+dis[k][j])
dis[i][j]=dis[i][k]+dis[k][j];
}
}
int ans=INF;
for(int i=1;i<=m;i++)
ans=min(ans,dis[i][i]);
printf("%d\n",ans==INF?-1:ans);
return 0;
}

posted @ 2017-06-13 22:19  Zars19  阅读(371)  评论(0编辑  收藏  举报