# BZOJ 1027 合金

3 2
0.25 0.25 0.5
0 0.6 0.5
1 0 0
0.7 0.1 0.2
0.85 0.05 0.1

2

## Source

  1 #include<ctime>
2 #include<iostream>
3 #include<cstring>
4 #include<cmath>
5 #include<algorithm>
6 #include<cstdio>
7 #include<cstdlib>
8 using namespace std;
9
10 #define rhl 100
11 #define inf (1<<29)
12 #define esp (1e-10)
13 #define maxn 510
14 int ans = inf,m,n,tot,dis[maxn][maxn];
15 bool in[maxn];
16
17 inline double equal(double a,double b) { return fabs(a-b) < esp; }
18
19 inline bool dd(double a,double b) { if (equal(a,b)) return true; return a >= b; }
20 inline bool dy(double a,double b) { if (equal(a,b)) return false; return a > b; }
21
22 inline bool xd(double a,double b) { if (equal(a,b)) return true; return a <= b; }
23
24 struct NODE
25 {
26     double x,y;
27     friend inline bool operator == (NODE a,NODE b) { return equal(a.x,b.x)&&equal(a.y,b.y); }
28     friend inline bool operator < (NODE a,NODE b) { if (a.x == b.x) return a.y < b.y; return a.x < b.x; }
29     friend inline NODE operator - (NODE a,NODE b) { return (NODE) {a.x - b.x,a.y - b.y}; }
30     friend inline double operator / (NODE a,NODE b) { return a.x*b.y-a.y*b.x; }
31     inline NODE ra()
32     {
33         int xx,yy;
34         do xx = rand()%rhl,yy = rand()%rhl;
35         while (equal(1.0*xx,x)||equal(1.0*yy,y));
36         return (NODE) {1.0*xx,1.0*yy};
37     }
38     inline void read() { scanf("%lf %lf",&x,&y); }
39 }pri[maxn],aim[maxn],ch[maxn];
40 struct LINE
41 {
42     double a,b,c;
43     inline bool on(NODE p) { return equal(0,a*p.x+b*p.y+c); }
44 };
45 struct SEG
46 {
47     NODE a,b;
48     inline LINE extend() { return (LINE) {a.y-b.y,b.x-a.x,b.y*(a.x-b.x)-b.x*(a.y-b.y)}; }
49     inline bool on(NODE p)
50     {
51         if (p == a) return true;
52         if (p == b) return true;
53         return (dd(p.x,min(a.x,b.x))&xd(p.x,max(a.x,b.x)))&&(dd(p.y,min(a.y,b.y))&xd(p.y,max(a.y,b.y)));
54     }
55 };
56
57 inline bool para(LINE l1,LINE l2) { return equal(l1.a * l2.b,l1.b * l2.a); }
58
59 inline NODE cp(LINE l1,LINE l2)
60 {
61     double a1 = l1.a,b1 = l1.b,c1 = l1.c;
62     double a2 = l2.a,b2 = l2.b,c2 = l2.c;
63     double ry = (c2*a1-c1*a2)/(b1*a2-b2*a1),rx = (c1*b2-c2*b1)/(b1*a2-b2*a1);
64     return (NODE) {rx,ry};
65 }
66
67 inline void convex()
68 {
69     sort(aim+1,aim+n+1);
70     n = unique(aim+1,aim+n+1) - aim - 1;
71     for (int i = 1;i <= n;++i)
72     {
73         while (tot > 1 &&(ch[tot] - ch[tot - 1])/(aim[i] - ch[tot-1]) <= 0) --tot;
74         ch[++tot] = aim[i];
75     }
76     int k = tot;
77     for (int i = n-1;i;--i)
78     {
79         while (tot > k &&(ch[tot] - ch[tot - 1])/(aim[i] - ch[tot-1]) <= 0) --tot;
80         ch[++tot] = aim[i];
81     }
82     if (n > 1) --tot;
83     ch[0] = ch[tot];
84 }
85
86 inline int find(NODE p)
87 {
88     NODE q = p.ra(); SEG s = (SEG) {p,q},t; LINE l = s.extend(),l1; int cnt;
89     cnt = 0;
90     for (int i = 1;i <= tot;++i)
91     {
92         t = (SEG) {ch[i],ch[i-1]};
93         if ((t.extend()).on(p)&&t.on(p)) return false;
94         l1 = t.extend();
95         if (para(l,l1)) continue;
96         q = cp(l,l1);
97         if (dd(q.x,p.x)&&t.on(q)) ++cnt;
98     }
99     if (cnt & 1) return true;
100     return false;
101 }
102
103 inline bool cross(NODE p,NODE q)
104 {
105     for (int i = 1;i <= tot;++i)
106         if (dy((q - p) / (ch[i] - p),0)) return false;
107     return true;
108 }
109
111 {
112     sort(pri+1,pri+m+1);
113     m = unique(pri+1,pri+m+1) - pri - 1;
114     for (int i = 1;i <= m;++i) in[i] = find(pri[i]);
115     memset(dis,0x7,sizeof(dis));
116     for (int i = 1;i <= m;++i) if (!in[i])
117         for (int j = 1;j <= m;++j)
118             if (i != j && !in[j] &&dis[j][i] > maxn)
119                 if (cross(pri[i],pri[j]))
120                     dis[i][j] = 1;
121 }
122
123 inline void floyd()
124 {
125     for (int k = 1;k <= m;++k)
126         for (int i = 1;i <= m;++i)
127             if (dis[i][k] < maxn)
128                 for (int j = 1;j <= m;++j)
129                     dis[i][j] = min(dis[i][j],dis[i][k]+dis[k][j]);
130     for (int i = 1;i <= m;++i) ans = min(dis[i][i],ans);
131     if (ans > maxn) ans = -1;
132     for (int i = 1;i <= m;++i)
133         for (int j = i+1;j <= m;++j)
134         {
135             SEG s = (SEG) {pri[i],pri[j]}; int k;
136             for (k = 1;k <= n;++k)
137                 if (!(equal((aim[k]-pri[i])/(aim[k]-pri[j]),0)&&s.on(aim[k]))) break;
138             if (k == n + 1) { ans = 2; break; }
139         }
140     printf("%d",ans);
141 }
142
143 inline void spj() { if (n == 1) for (int i = 1;i <= m;++i) if (pri[i] == aim[1]) puts("1"),exit(0);  }
144
145 int main()
146 {
147     freopen("1027.in","r",stdin);
148     freopen("1027.out","w",stdout);
149     srand(233);
150     scanf("%d %d",&m,&n); double w;
151     for (int i = 1;i <= m;++i)
153     for (int i = 1;i <= n;++i)
161 }