bzoj 1027: [JSOI2007]合金

由于总和一定所以看前两个即可,可以他们抽象成平面上的点,两个点能合出来的点在以两点为端点的线段上,三个点的在以三点为顶点的三角形内,。。。

所以预先处理那两个点的连线在所有被需要的点的一边,便把距离设为1,跑一遍最小环就行了。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<queue>
  7 #include<algorithm>
  8 #define M 509
  9 #define EPS 1e-10
 10 #define ll long long
 11 using namespace std;
 12 ll read()
 13 {
 14     char ch=getchar();
 15     ll x=0,f=1;
 16     for(;ch<'0'||ch>'9';ch=getchar())
 17         if(ch=='-')
 18           f=-1;
 19     for(;ch>='0'&&ch<='9';ch=getchar())
 20         x=x*10+ch-'0';
 21     return x*f;
 22 }
 23 int n,m,f[M][M],mx=707406378;
 24 struct data
 25 {
 26     double x,y;
 27 }a[M],b[M];
 28 data operator -(data a1,data a2)
 29 {
 30    data a3;
 31    a3.x=a1.x-a2.x;
 32    a3.y=a1.y-a2.y;
 33    return a3;
 34 }
 35 int jin(data a1,data a2)
 36 {
 37    double a3=a1.x*a2.y-a1.y*a2.x;
 38    if(a3>EPS)
 39       return 1;
 40    if(a3<-EPS)
 41       return -1;
 42    return 0;
 43 }
 44 int cheng(data a1,data a2)
 45 {
 46   double a3=a1.x*a2.x+a1.y*a2.y;
 47    if(a3>EPS)
 48       return 1;
 49    if(a3<-EPS)
 50       return -1;
 51    return 0;
 52 }
 53 bool pan1()
 54 {
 55   for(int i=1;i<=n;i++)
 56     {
 57       int sum=0;
 58       for(int j=1;j<=m;j++)
 59         if(a[i].x==b[j].x&&a[i].y==b[j].y)
 60           sum++;
 61         else
 62           break;
 63       if(sum==m)
 64         return 1;
 65     }
 66   return 0;
 67 }
 68 bool pan2()
 69 {
 70   for(int i=3;i<=m;i++)
 71     if(jin(a[i]-a[1],a[2]-a[1])!=0)
 72       return 0;
 73   for(int i=1;i<=n;i++)
 74     for(int j=1;j<=n;j++)
 75       {
 76         int sum=0;
 77         for(int k=1;k<=m;k++)
 78           if(cheng(a[i]-b[k],a[j]-b[k])<=0)
 79             sum++;
 80         if(sum==m)
 81           return 0;
 82       }
 83   return 1;
 84 }
 85 int main()
 86 {
 87     n=read();
 88     m=read();
 89     for(int i=1;i<=n;i++)
 90         {
 91             double a1;
 92             scanf("%lf%lf%lf",&a[i].x,&a[i].y,&a1);
 93         }
 94     for(int i=1;i<=m;i++)
 95         {
 96             double a1;
 97             scanf("%lf%lf%lf",&b[i].x,&b[i].y,&a1);
 98         }
 99     if(pan1())
100       {
101         printf("1\n");
102         return 0; 
103       }
104     if(pan2())
105       {
106         printf("-1\n");
107         return 0;
108       }
109     memset(f,127/3,sizeof(f));
110     for(int i=1;i<=n;i++)
111       for(int j=1;j<=n;j++)
112       if(i!=j)
113        {
114          data a1=a[j]-a[i];
115          int kg=1;
116          for(int k=1;k<=m;k++)
117            if(jin(a1,b[k]-a[i])<0)
118              {
119                kg=0;
120                break;
121              }
122          if(kg)
123            f[i][j]=kg;
124        }
125        for(int k=1;k<=n;k++)
126      for(int i=1;i<=n;i++)
127        for(int j=1;j<=n;j++)
128              f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
129        for(int i=1;i<=n;i++)
130          mx=min(mx,f[i][i]);
131        if(mx==707406378)
132          mx=-1;
133        printf("%d\n",mx);
134    return 0;
135 }
136 

 

posted @ 2016-07-07 07:50  xiw5  阅读(163)  评论(0编辑  收藏  举报