[BZOJ1027][JSOI2007]合金
来源:互联网 发布:宁夏领导干部网络培训 编辑:程序博客网 时间:2024/04/27 23:57
[JSOI2007]合金
Description
某公司加工一种由铁、铝、锡组成的合金。他们的工作很简单。首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同。然后,将每种原材料取出一定量,经过融解、混合,得到新的合金。新的合金的铁铝锡比重为用户所需要的比重。 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重。公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金。
Input
第一行两个整数m和n(m, n ≤ 500),分别表示原材料种数和用户需要的合金种数。第2到m + 1行,每行三个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种原材料中所占的比重。第m + 2到m + n + 1行,每行三个实数a, b, c(a, b, c ≥ 0 且 a + b + c = 1),分别表示铁铝锡在一种用户需要的合金中所占的比重。
Output
一个整数,表示最少需要的原材料种数。若无解,则输出–1。
Sample Input
10 10
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
0.1 0.2 0.7
0.2 0.3 0.5
0.3 0.4 0.3
0.4 0.5 0.1
0.5 0.1 0.4
0.6 0.2 0.2
0.7 0.3 0
0.8 0.1 0.1
0.9 0.1 0
1 0 0
Sample Output
5
Solution
首先前两维符合要求之后第三维自然符合,无视
两个材料能合成的所有合金在它们的连线的线段上
若干材料能合成的所有合金在它们的凸包内
那么我们要用最少的点构成的凸包囊括所有的要求点
枚举两个材料,如果所有合金在它们分割成的一个半平面里,就连一条有向边
然后就是最小环
Code
#include <bits/stdc++.h>using namespace std;#define rep(i, l, r) for (int i = (l); i <= (r); i++)#define per(i, r, l) for (int i = (r); i >= (l); i--)#define MS(_, __) memset(_, __, sizeof(__))#define MP make_pair#define PB push_backtypedef long long ll;typedef pair<int, int> PII;template<typename T> inline void read(T &x){ x = 0; T f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-') f = -1; ch = getchar();} while (isdigit(ch)) {x = x * 10 + ch - '0'; ch = getchar();} x *= f;}const int INF = 1e9;const double eps = 1e-8;struct Vec{ double x, y; Vec() {} Vec(double _x, double _y) : x(_x), y(_y) {} inline double angle() const{ return atan2(y, x); } inline double len() const{ return sqrt(x*x+y*y); } inline Vec l_rot() const{ return Vec(-y, x); } inline Vec r_rot() const{ return Vec(y, -x); }};inline Vec operator + (const Vec &a, const Vec &b) { return Vec(a.x+b.x, a.y+b.y); }inline Vec operator - (const Vec &a, const Vec &b) { return Vec(a.x-b.x, a.y-b.y); }template<typename T> inline Vec operator * (const Vec &a, T b) { return Vec(a.x*b, a.y*b); }template<typename T> inline Vec operator * (T a, const Vec &b) { return Vec(a*b.x, a*b.y); }template<typename T> inline Vec operator / (const Vec &a, T b) { return Vec(a.x/b, a.y/b); }inline double cross(const Vec &a, const Vec &b) { return a.x*b.y-a.y*b.x; }inline double dot(const Vec &a, const Vec &b) { return a.x*b.x+a.y*b.y; }typedef Vec Poi;inline bool le(double x, double y) { return x-y<=eps; }inline bool lt0(double x) { return x<-eps; }inline bool gt0(double x) { return x>eps;}inline bool eq0(double x) { return abs(x)<=eps; } inline bool between(Poi m, Poi l, Poi r) { return le(min(l.x,r.x),m.x)&&le(m.x,max(l.x,r.x)); }int n, m;Vec goal[510], given[510];int g[510][510];inline void spj(){ if (n == 1){ bool flag = true; rep(i, 1, m) if (goal[i].x != given[1].x || goal[i].y != given[1].y) flag = false; puts(flag ? "1" : "-1"); exit(0); }}int main(){ read(n); read(m); rep(i, 1, n) scanf("%lf%lf%*lf", &given[i].x, &given[i].y); rep(i, 1, m) scanf("%lf%lf%*lf", &goal[i].x, &goal[i].y); spj(); rep(i, 1, n) rep(j, 1, n) g[i][j] = INF; rep(dot1, 1, n) rep(dot2, dot1+1, n){ Vec p = given[dot1]-given[dot2]; bool flag1 = false, flag2 = false, flag3 = false; rep(dot3, 1, m){ double t = cross(p, goal[dot3]-given[dot2]); if (lt0(t)) flag1 = true; if (gt0(t)) flag2 = true; if (eq0(t) && gt0(dot(goal[dot3]-given[dot2], goal[dot3]-given[dot1]))) flag3 = true; if ((flag1 && flag2) || flag3) break; } if (flag1 && flag2) continue; if (flag3) continue; if (flag1) g[dot1][dot2] = 1; else if (flag2) g[dot2][dot1] = 1; else g[dot1][dot2] = g[dot2][dot1] = 1; } int ans = INF; rep(k, 1, n) rep(i, 1, n) rep(j, 1, n) g[i][j] = min(g[i][j], g[i][k]+g[k][j]); rep(i, 1, n) ans = min(ans, g[i][i]); if (ans > n) puts("-1"); else printf("%d\n", ans); return 0;}
- [BZOJ1027][JSOI2007]合金
- BZOJ1027: [JSOI2007]合金
- 【JSOI2007】bzoj1027 合金
- bzoj1027: [JSOI2007]合金
- [JSOI2007]合金
- bzoj 1027: [JSOI2007] 合金
- 【BZOJ 1027】 [JSOI2007]合金
- 1027: [JSOI2007]合金
- 1027: [JSOI2007]合金
- 【BZOJ 1027】[JSOI2007]合金
- BZOJ 1027 [JSOI2007]合金
- BZOJ P1027[JSOI2007]合金
- bzoj1027 合金 Floyd求最小环 + 计算几何
- BZOJ 1027 JSOI2007 合金 计算几何+Floyd
- bzoj 1027 [JSOI2007]合金 计算几何+floyd
- [BZOJ]1027: [JSOI2007]合金 计算几何+floyd
- bzoj 1027: [JSOI2007]合金(floyd最小环)
- 合金
- 码农小汪-Hibernate学习3-Mapping declaration 映射定义
- HTML-文本格式化
- FEC之我见四
- C#获取exe的路径
- POJ1324 Holedox Moving(BFS)
- [BZOJ1027][JSOI2007]合金
- 第十二章 类和动态内存分配
- Java运行时异常和一般异常
- Android学习之定时执行后台任务
- BlocksKit 简单使用
- linux screen 命令详解
- 手机使用Fiddler抓包
- 给15个数排序
- java中的异常