【bzoj 十连测】[noip2016十连测第九场]Problem C: 小P的生成树(kruskal+数学知识)
2016-11-17 10:09
405 查看
【题解】【kruskal】
【因为要使生成树的边长和模长最大,那么只需每个复数在其方向向量的投影最大。so,可以把投影作为权值来做最大生成树。】
【kruskal的理论告诉我们:生成树的大小只与各边的相对边长有关,也就是说,只需考虑各边的大小关系尽量选权值大的边建生成树就行】
【考虑两边权值:x1+yi1和x2+yi2(y1≠y2),当两边的复数的投影相等时,方向向量需要满足:x1cosθ+y1sinθ=x2cosθ+y2sinθ,化简后tanθ1=y2−y1x1−x2,θ2=arctany2−y1x1−x2+π;而当x1≠x2,y1=y2时,等式化为x1cosθ=x2cosθ=>cosθ=0=>θ1=π2,θ2=3π2】
【枚举每一对边,算出两条边投影相等时极角的分界点,此时会把区间[−π2,3π2]分为若干个小区间,由于每条边的投影大小关于极角的变化是连续的,所以在每个小区间里权值的大小关系不发生改变。】
【枚举每个区间,做最大生成树】
[复数处理时,和实数是相似的]
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; struct node{ int x,y; double a,b,way; }d[410]; int fa[110],cnt,n,m; double ans,f[80010]; int tmp(node p,node q) { return p.way>q.way; } int find(int x) { if(fa[x]==x) return fa[x]; fa[x]=find(fa[x]); return fa[x]; } inline double shorter(double x) { double cs=cos(x); double sn=sin(x); for(int i=1;i<=m;++i) d[i].way=cs*d[i].a+sn*d[i].b; sort(d+1,d+m+1,tmp); for(int i=1;i<=n;++i)fa[i]=i; double A=0,B=0; for(int i=1,cnt=1;i<=m;++i) { int l1=find(d[i].x),l2=find(d[i].y); if(l1!=l2) { A+=d[i].a; B+=d[i].b; fa[l1]=l2; ++cnt; if(cnt==n) return (A*A+B*B); } } } inline void solve() { cnt=0; ans=-1; for(int i=1;i<m;++i) for(int j=i+1;j<=m;++j) { double x1=d[i].a,y1=d[i].b,x2=d[j].a,y2=d[j].b; if(y1>y2) swap(x1,x2),swap(y1,y2); if(y1==y2) {f[++cnt]=M_PI/2; f[++cnt]=-M_PI/2; continue;} f[++cnt]=atan((x1-x2)/(y2-y1)); f[cnt+1]=f[cnt]+M_PI; cnt++; } f[++cnt]=-M_PI/2; f[++cnt]=M_PI*5/2; sort(f+1,f+cnt+1); cnt=unique(f+1,f+cnt+1)-f-1; for(int i=1;i<=cnt;++i) ans=max(ans,shorter((f[i]+f[i-1])/2)); if(ans<0) printf("-1\n"); else printf("%.6lf\n",sqrt(ans)); return; } int main() { freopen("int.txt","r",stdin); int i,j; scanf("%d%d",&n,&m); for(i=1;i<=m;++i)scanf("%d%d%lf%lf",&d[i].x,&d[i].y,&d[i].a,&d[i].b); solve(); return 0; }
相关文章推荐
- 【bzoj 十连测】[noip2016十连测第九场]Problem B: 小P的单调区间(最长上升子序列+树状数组)
- 【bzoj 十连测】[noip2016十连测第四场]Problem A: 天空龙(数学相关)
- 【bzoj 十连测】[noip2016十连测第五场]Problem A: simple(bfs)
- [BZOJbegin][NOIP十连测第九场]小P的生成树(数学相关+kruskal)
- 【bzoj 十连测】[noip2016十连测第五场]Problem B: walk(dfs求最长链)
- 【bzoj 十连测】[noip2016十连测第五场]Problem C: travel(模拟)
- 【bzoj 十连测】[noip2016十连测第七场]Problem A: 约瑟夫游戏(递推+打表)
- 【bzoj 十连测】[noip2016十连测第八场]Problem B: 降雷皇(最长上升子序列+线段树|next数组)
- 【bzoj 十连测】[noip2016十连测第二场]Problem C. Dash Speed(树链剖分+并查集)
- 【bzoj 十连测】[noip2016十连测第三场]Problem A: 平均数(二分答案+归并排序求逆序对)
- 【bzoj 十连测】[noip2016十连测第八场]Problem C: 幻魔皇(递推)
- 【bzoj 十连测】[noip2016十连测第二场]Problem B. Market(dp:01背包)
- 【bzoj 十连测】[noip2016十连测第八场]Problem A: 神炎皇(数学相关:线性筛)
- 【bzoj 十连测】[noip2016十连测第三场]Problem C: 序列(静态主席树)
- [BZOJbegin][noip2016十连测第九场]小P的单调区间(dp+bit)
- 【bzoj 十连测】[noip2016第一场]Problem C. Walk(dfs)
- [BZOJbegin][NOIP十连测第九场]小P的2048(模拟)
- [BZOJbegin][NOIP十连测第九场]小P的单调数列(数学相关+dp+bit)
- 【bzoj 十连测】[noip2016第一场]Problem A: String Master(暴力)
- 【bzoj 十连测】[noip2016第二场]Problem A. Divisors(暴力)