[CSP-S模拟测试]:小P的生成树(数学+Kruskal)
题目描述
小$P$是个勤于思考的好孩子,自从学习了最大生成树后,他就一直在想:能否将边权范围从实数推广到复数呢?可是马上小$P$就发现了问题,复数之间的大小关系并没有定义。于是对于任意两个复数$z_1,z_2$,小$P$定义$z_1<z_2$当且仅当$|z_1|<|z_2|$。
现在,给出一张$n$个点$m$条边的简单无向带权图,小$P$想问你,如果按照他对复数大小的定义,这个图的最大生成树是什么?
输入格式
输入的第一行为两个正整数$n$和$m$,分别表示这个无向图的点数和边数。
接下来$m$行,每行四个整数$u,v,a,b(1\leqslant u,v\leqslant n,-1000\leqslant a,b\leqslant 1000)$,表示点$u$与点$v$之间有一条无向边,边权为$a+bi$。
输出格式
输出仅有一个实数,它等于所有的最大生成树中所有边权之和的模长。
实数四舍五入,保留六位小数。
样例
样例输入1:
3 3
1 2 1 3
2 3 2 2
3 1 3 1
样例输出1:
5.830952
样例输入2:
6 9
1 2 4 -1
2 3 4 1
3 4 -1 -5
1 5 -4 0
4 6 1 -6
2 6 -6 0
5 6 -7 5
2 4 7 1
1 4 -9 -5
样例输出2:
27.459060
数据范围与提示
样例$1$解释:
显然,从该图三条边中任取两条便可以构成一棵生成树,这三棵生成树的边权之和分别为$z_1=3+5i,z_2=4+4i,z_3=5+3i$,其中$|z_2|=\sqrt{32}<|z_1|=|z_3|=\sqrt{34}$。
数据范围:
对于$10\%$的数据:$n\leqslant 6$
对于$30\%$的数据:$n\leqslant 12$
对于另外$20\%$的数据:每条边的边权均为实数
对于$100\%$的数据:$n\leqslant 50,m\leqslant 200$,给定的无向图至少存在一个生成树
提示:
简单无向图的定义为:没有任何重边和自环的无向图。
若复数$z_1=a_1+b_1i,z_2=a_2+b_2i$,则$z_1+z_2=(a_1+a_2)+(b_1+b_2)i$。
设复数$z=a+bi$,符号$|z|=\sqrt{a^2+b^2}$表示该复数的模长。
若复数$z=a+bi$满足条件$b=0$,则该复数为实数。
题解
假设我们已经知道了生成树中各边求和所得复数的单位方向向量,那么要使得生成树的边权和模长最大,只需各复数在该方向向量上的投影之和最大。于是,我们将每条边对应的复数在该方向向量上的投影作为其新的权值,做一遍最大生成树即可解决。
但是显然我们不能枚举所有的方向向量。
但是根据$kruskal$的算法流程我们可以知道:
生成树的形态只与各边边权的相对大小有关,而与具体权值无关。
不妨设两条边,其边权分别是$x_1+y_1i$和$x_2+y_2i(y_1\neq y_2)$当两条边对应的复数投影相等时,方向向量$(\cos\theta,\sin\theta)$需要满足:$x_1\cos\theta+y_1\sin\theta=x_2\cos\theta+y_2\sin\theta$,化简后得$\tan\frac{x_1-x_2}{y_2-y_1}\Rightarrow\theta 1=\arctan\frac{x_1-x_2}{y_2-y_1},\theta 2=\arctan\frac{x_1-x_2}{y_2-y_1}+\pi$。而当$y_1=y_2,x_1\neq x_2$时,等式化为$x_1\cos\theta=x_2\cos\theta\Rightarrow \cos\theta=0\Rightarrow \theta 1=\frac{\pi}{2},\theta 2=\frac{3\pi}{2}$。
那么,我们可以枚举每一对边,算出两条边投影相等时计较的分解点,此时这些分解点会把$[-\frac{\pi}{2},\frac{3\pi}{2})$的极角分成若干个小区间。由于每条变得投影大小关于极角$\theta$是连续变化的,所以在每个小极角区间内,所有边的投影相对大小关系不变。
于是我们可以对于每个区间任取一个方向向量做最大生成树,最后取最优方案即可。
需要注意的是因为$\arctan$无法求出$\frac{\pi}{2}$和$\frac{3\pi}{2}$,所以要插入这两个值。
时间复杂度:$\Theta(m^3\log m)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
struct rec{int x,y;double a,b,s;}e[201];
int n,m,cnt;
int fa[51];
double ans,theta[40001];
bool cmp(rec a,rec b){return a.s>b.s;}
int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}
double kruskal(double x)
{
int res=0;
double a=0.0,b=0.0;
for(int i=1;i<=m;i++)e[i].s=e[i].a*sin(x)+e[i].b*cos(x);
sort(e+1,e+m+1,cmp);
for(int i=1;i<=n;i++)fa[i]=i;
for(int i=1;i<=m;i++)
{
int x=find(e[i].x),y=find(e[i].y);
if(x==y)continue;
fa[x]=y;
res++;
a+=e[i].a;
b+=e[i].b;
if(res==n-1)break;
}
return a*a+b*b;
}
int main()
{
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++)
scanf("%d%d%lf%lf",&e[i].x,&e[i].y,&e[i].a,&e[i].b);
for(int i=1;i<=m;i++)
for(int j=i+1;j<=m;j++)
if(e[i].b==e[j].b)theta[++cnt]=M_PI/2.0;
else{theta[++cnt]=atan((e[i].a-e[j].a)/(e[j].b-e[i].b));theta[++cnt]=theta[cnt-1]+M_PI;}
theta[++cnt]=-M_PI/2.0;
theta[++cnt]=M_PI*3.0/2.0;
sort(theta+1,theta+cnt+1);
cnt=unique(theta+1,theta+cnt+1)-theta-1;
for(int i=1;i<=cnt;i++)ans=max(ans,kruskal(theta[i]));
printf("%.6lf",sqrt(ans));
return 0;
}
rp++
[CSP-S模拟测试]:小P的生成树(数学+Kruskal)的更多相关文章
- [CSP-S模拟测试]:小P的2048(模拟)
题目描述 最近,小$P$迷上了一款叫做$2048$的游戏.这块游戏在一个$n\times n$的棋盘中进行,棋盘的每个格子中可能有一个形如$2^k(k\in N^*)$的数,也可能是空的.游戏规则介绍 ...
- [CSP-S模拟测试]:小L的数(数位DP+模拟)
题目传送门(内部题132) 输入格式 第一行一个整数$t$. 接下来$t$行每行一个整数$n$. 输出格式 $t$行,每行一个整数表示答案. 样例 样例输入: 41818231232691052109 ...
- [CSP-S模拟测试]:小盆友的游戏(数学 or 找规律)
题目传送门(内部题110) 输入格式 第一行一个整数$N$,表示小盆友的个数. 第二行$N$个整数$A_i$,如果$A_i=-1$表示$i$目前是自由身,否则$i$是$A_i$的跟班. 输出格式 一个 ...
- [CSP-S模拟测试]:小P的单调数列(树状数组+DP)
题目描述 小$P$最近喜欢上了单调数列,他觉得单调的数列具有非常多优美的性质.经过小$P$复杂的数学推导,他计算出了一个单调增数列的艺术价值等于该数列中所有书的总和.并且以这个为基础,小$P$还可以求 ...
- [CSP-S模拟测试]:小奇的仓库(warehouse)(树形DP)
题目背景 小奇采的矿实在太多了,它准备在喵星系建个矿石仓库.令它无语的是,喵星系的货运飞船引擎还停留在上元时代! 题目描述 喵星系有$n$个星球,星球以及星球间的航线形成一棵树.从星球$a$到星球$b ...
- [CSP-S模拟测试]:小奇的矩阵(matrix)(DP+数学)
题目背景 小奇总是在数学课上思考奇怪的问题. 题目描述 给定一个$n\times m$的矩阵,矩阵中的每个元素$a_{i,j}$为正整数.接下来规定: $1.$合法的路径初始从矩阵左上角出发,每 ...
- [CSP-S模拟测试]:小奇挖矿2(DP+赛瓦维斯特定理)
题目背景 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿石交易市场,以便为飞船升级无限非概率引擎. 题目描述 现在有$m+1$个星球,从左到右标号为$0$到$n$,小奇最初 ...
- [CSP-S模拟测试]:小Y的图(最小生成树+LCA)
题目传送门(内部题131) 输入格式 第一行三个整数$n$.$m$和$Q$. 接下来$m$行每行三个整数$x$.$y$.$z$($1\leqslant x,y\leqslant n,1\leqslan ...
- [CSP-S模拟测试]:小W的魔术(数学 or 找规律)
题目传送门(内部题130) 输入格式 第一行一个整数$n$,表示字符串的长度. 第二行一个只包含小写字母的字符串$s$. 输出格式 一行一个整数表示答案对$998244353$取模后的结果. 样例 样 ...
随机推荐
- 配置DHCP中继
本实验模拟企业网络场景.某公司分部的网络由交换机S1和网关路由器R1组成,员工终端PC-1和PC-2都连接在S1上.公司要求分部内所有员工主机的IP地址都通过总部的DHCP服务器自动获取.分部网关路由 ...
- 自动构建War包的Ant build.xml模板
<?xml version="1.0" encoding="UTF-8" ?> <project name="[*****]你的项目 ...
- IntelliJ IDLE
目录 IntelliJ IDLE java项目结构 代码生成 psvm sout 快捷键 更改代码提示快捷键 代码相关快捷键 窗口相关快捷键 Debug快捷键 主题导入 下载主题 导入主题 应用主题 ...
- 封装 多态 类的约束 super
python面向对象的三大特性:继承,封装,多态. 1. 封装: 把很多数据封装到⼀个对象中. 把固定功能的代码封装到⼀个代码块, 函数, 对象, 打包成模块. 这都属于封装的思想. 具体的情况具体分 ...
- [51Nod1850] 抽卡大赛
link $solution:$ 朴素 $dp$,暴力枚举选择 $i$ 号人的第 $j$ 张卡片,朴素 $dp$ 即可,时间复杂度 $O(n^4)$ . 考虑对于朴素 $dp$ 的优化,发现其实是一个 ...
- asp.net table表格表头及列固定实现
http://blog.csdn.net/zdw_wym/article/details/48630337 在开发中常会遇到table表格中列特别多,下拉后,表头就看不见了,水平滚动后,第1.2列就看 ...
- windows和linux安装rabbitmq
一.windows安装rabbitmq 1.安装erlang 点击进入官网下载:http://erlang.org/download/ 2.安装rabbitmq 点击进入官网下载:http://www ...
- 使用axios发送ajax请求
1.安装 npm install axios 2.在Home.vue中引入 import axios from 'axios' export default { name: 'Home', c ...
- css控制文本内容显示省略号
1,单行文字显示省略号 div{ width:200px; overflow:hideen; white-space:nowrap; text-overflow:ellipsis; } 2,多行文字显 ...
- Docker拷贝宿主机与容器中的文件
如果我们需要将宿主机文件拷贝到容器内可以使用 docker cp 命令,也可以将文件从容器内拷贝到宿主机 将宿主机文件拷贝到容器内 docker cp 要拷贝的宿主机文件或目录 容器名称:容器文件或目 ...