BZOJ 1027 JSOI2007 合金 计算几何+Floyd

题目大意:给定一些合金,选择最少的合金,使这些合金能够按比例合成要求的合金

首先这题的想法特别奇异 看这题干怎么会想到计算几何 并且计算几何又怎么会跟Floyd挂边 好强大

首先因为a+b+c=1 所以我们仅仅要得到a和b就可以 c=1-a-b 所以c能够不读入了

然后我们把每种原料抽象成一个点 可知两个点能合成的合金一定在两点连线的线段上

证明:设两个点为(x1,y1)和(x2,y2),新合成的合金为(ax1+bx2,ay2+by2) (a+b=1,a,b>0) 两点连线为(y-y1)/(x-x1)=(y-y2)/(x-x2),代入就可以得证

那么我们选定一些原料。这些原料能合成的合金一定在这些点所在的凸包上 证明略

于是我们就把问题转化成了这样:给定两个点集A和B,求A中最小的一个子集S。使B中全部的点在S的凸包内部

这个问题怎么处理呢?这里用到一个十分巧妙的方法

如图,枚举A点集两点i,j(i能够等于j)若B点集中的全部点都在向量i->j的左側或线段ij上(图中红色的点)而没有点在图中绿色的点所在位置。就连接一条i->j的单向边

即 若随意B点集中的点k满足(k->i)×(k->j)<0||(k->i)×(k->j)==0&&(k->i)·(k->j)<=0 则连接一条i->j的单向边

然后Floyd求最小环就可以

正确性自己YY吧 这样写应该是能够降低非常多讨论而且不会被卡掉的 顺便吐槽一句数据实在太弱……

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 510
#define INF 0x3f3f3f3f
#define EPS 1e-7
using namespace std;
struct point{
	double x,y;
	point operator - (const point z)
	{
		point re;
		re.x=x-z.x;
		re.y=y-z.y;
		return re;
	}
	double operator * (const point z)
	{
		return x*z.y-y*z.x;
	}
	double operator ^ (const point z)//大家好我是萌萌哒的点积 乘号被叉积抢了主人仅仅能给我这个了~
	{
		return x*z.x+y*z.y;
	}
}a[M],b[M];
int m,n;
int map[M][M],f[M][M];
int ans=INF;
void Floyd()
{
	int i,j,k;
	memcpy(f,map,sizeof f);
	for(k=1;k<=m;k++)
		for(i=1;i<=m;i++)
			if(f[i][k]<INF)
				for(j=1;j<=m;j++)
					f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
	for(i=1;i<=m;i++)
		ans=min(ans,f[i][i]);
}
int main()
{
	int i,j,k;
	memset(map,0x3f,sizeof map);
	cin>>m>>n;
	for(i=1;i<=m;i++)
		scanf("%lf%lf%*lf",&a[i].x,&a[i].y);
	for(i=1;i<=n;i++)
		scanf("%lf%lf%*lf",&b[i].x,&b[i].y);
	for(i=1;i<=m;i++)
		for(j=1;j<=m;j++)
		{
			for(k=1;k<=n;k++)
			{
				double cross=(a[i]-b[k])*(a[j]-b[k]);
				if( cross>EPS )
					break;
				if( fabs(cross)<EPS && (a[i]-b[k]^a[j]-b[k])>EPS )
					break;
			}
			if(k==n+1)
				map[i][j]=1;
		}
	Floyd();
	if(ans==INF)
		ans=-1;
	cout<<ans<<endl;
}
时间: 2024-11-07 18:53:39

BZOJ 1027 JSOI2007 合金 计算几何+Floyd的相关文章

bzoj 1027[JSOI2007]合金 - floyd + 凸包

1027: [JSOI2007]合金 Time Limit: 4 Sec  Memory Limit: 162 MB Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的铁铝锡比重为用户所需要的比重. 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重.公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要

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

Description 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的铁铝锡比重为用户所需要的比重. 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重.公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金. Solution 今天考试T3的70分算法似乎是这道原题(然而我没做过QwQ) 思路值得学习一下(

[bzoj 1027][JSOI2007]合金(解析几何+最小环)

题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1027 分析: 首先因为一个合金的和为1,所以考虑2个材料合金能否合成一个需求合金的时候,只要考虑前两个值就可以了. 我们如果把这两个值放到平面直角坐标系中,设两个材料合金坐标分别为(x,y)和(m,n),那么易得这两个材料合金可以合成的需求合金对应的点在(x,y)(m,n)两点之间的线段上.(高中数学向量的性质可以证) 那么问题就转化为了:平面上有m个材料合金点,n个需求合金点,要求

bzoj 1027: [JSOI2007]合金

由于总和一定所以看前两个即可,可以他们抽象成平面上的点,两个点能合出来的点在以两点为端点的线段上,三个点的在以三点为顶点的三角形内,... 所以预先处理那两个点的连线在所有被需要的点的一边,便把距离设为1,跑一遍最小环就行了. 1 #include<cstdio> 2 #include<iostream> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #include<

【BZOJ】1027: [JSOI2007]合金(凸包+floyd)

http://www.lydsy.com/JudgeOnline/problem.php?id=1027 没special judge wa了一发好蛋疼... 首先这题大概和黑书上的差不多...由于知道任意两种材料就能得到第三种材料的含量,所以可以忽略第三种含量... 首先来看,如果有两种材料,那么能合成的材料一定在这个线段上,证明很简单... 假设材料A和B,要合成材料C,将他们材料的含量放到二维坐标系上(x轴为材料1,y轴为材料2) 假设用了a的A,则用了1-a的B,有 $$\begin{a

【BZOJ 1027】 (凸包+floyd求最小环)

[题意] 某公司加工一种由铁.铝.锡组成的合金.他们的工作很简单.首先进口一些铁铝锡合金原材料,不同种类的原材料中铁铝锡的比重不同.然后,将每种原材料取出一定量,经过融解.混合,得到新的合金.新的合金的铁铝锡比重为用户所需要的比重. 现在,用户给出了n种他们需要的合金,以及每种合金中铁铝锡的比重.公司希望能够订购最少种类的原材料,并且使用这些原材料可以加工出用户需要的所有种类的合金. [分析] 只要考虑前两个物质的比例,因为加起来等于1. 如果你看过zoj3154,就会知道这题的模型,用二元组表

BZOJ_1027_[JSOI2007]_合金_(计算几何+Floyd求最小环)

描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1027 共三种金属,\(m\)种材料,给出每种材料中三种金属的占比. 给出\(n\)种合金的三种金属占比.用材料做合金,问最少需要多少种材料. 分析 首先,由于三种金属的占比相加为1,所以确定了前两项,最后一项也就确定了,我们可以用二唯坐标\((x,y)\)表示前两项,这样每种材料和合金就是二维平面上的一个点. 接下来是用材料做合金. 首先来考虑用两种材料做合金,两种材料为\((x1,y1)和

bzoj千题计划123:bzoj1027: [JSOI2007]合金

http://www.lydsy.com/JudgeOnline/problem.php?id=1027 因为x+y+z=1,所以z=1-x-y 第三维可以忽略 将x,y 看做 平面上的点 简化问题: 若只有两种 材料,那么可以合成 两点线段 上的所有的点 推广到多种材料: 若 用户点 在 材料点 构成的 凸包内,则可以合成 所以题目转化为 求材料点 组成的 能包含所有用户点 的 最小环 用Floyd 枚举 每两对材料点,若所有用户点在 在线段的左侧或在线段上 则 f[i][j]=1 表示i到j

BZOJ 1027 合金(凸包-最小环)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1027 题意:三种合金的材料若干种.需求合金若干种.每种需求合金可以由材料合金混合得到.问最少需要多少种材料能够混合出所有需要的合金? 思路:对于两种材料合金ab,若能够得到需 求合金p,那么p必在线段ab上.这里由于三种合金的和为1,只要二维就够了,也就是是一个二维的问题.那么问题转化成,在平面上,找出最少的点包含所有 的需求合金对应的点(答案为1和2特判一下就行).两两枚举材料合金x