民权平台网站建设,html5网站图标,网站建设指南 菜鸟教程,wordpress如何备份数据正题
题目链接:https://jzoj.net/senior/#contest/show/3002/1 题目大意 nnn个点mmm条边#xff0c;每条边有(u,v)(u,v)(u,v)两个权值。 qqq个询问#xff0c;每次询问一个(k1,k2)(k1,k2)(k1,k2)#xff0c;将所有边的权值变为u∗k1v∗k2u*k1v*k2u∗k1v∗k2后求最小生成树。…正题
题目链接:https://jzoj.net/senior/#contest/show/3002/1 题目大意
nnn个点mmm条边每条边有(u,v)(u,v)(u,v)两个权值。
qqq个询问每次询问一个(k1,k2)(k1,k2)(k1,k2)将所有边的权值变为u∗k1v∗k2u*k1v*k2u∗k1v∗k2后求最小生成树。 解题思路
首先u∗k1v∗k2⇒(uv∗k2k1)∗k1u*k1v*k2\Rightarrow (uv*\frac{k2}{k1})*k1u∗k1v∗k2⇒(uv∗k1k2)∗k1所以决策可以线性表示出来。
我们考虑维护一个坐标系(x,y)(x,y)(x,y)表示uuu值和为xxx的生成树中yyy值和最小是多少。
显然xxx增大时yyy在减小所以这是一个下突壳。
考虑维护这一个突壳首先是两个端点l:(k10,k21)l:(k10,k21)l:(k10,k21)时和r:(k11,k20)r:(k11,k20)r:(k11,k20)各做一次最小生成树此时我们考虑找到一个在线段(l,r)(l,r)(l,r)的左下角最远的点midmidmid。
通过差积各种证明后我们发现有mid(k1∣yl−yr∣,k2∣xl−xr∣)mid(k1|y_l-y_r|,k2|x_l-x_r|)mid(k1∣yl−yr∣,k2∣xl−xr∣)然后分治下去处理(l,mid)(l,mid)(l,mid)和(r,mid)(r,mid)(r,mid)。
当midmidmid在线段(l,r)(l,r)(l,r)上时证明左下角已经没有更优的点所以可以返回了。
最后在突壳上三分答案就好了。 codecodecode
#includecstdio
#includecstring
#includealgorithm
#includecmath
using namespace std;
const int M25100,N40;
struct node{int x,y;double u,v;
}a[M];
struct knode{double k1,k2,x,y;
}k[M*4],head,tail;
int n,m,q,fa[N],tot;
double k1,k2;
int find(int x)
{return fa[x]x?x:(fa[x]find(fa[x]));}
bool cmp(node x,node y)
{return x.u*k1x.v*k2y.u*k1y.v*k2;}
void Get_Tree(knode k){k1k.k1;k2k.k2;k.xk.y0;sort(a1,a1m,cmp);for(int i1;in;i)fa[i]i;int zn;for(int i1;im;i){int fxfind(a[i].x),fyfind(a[i].y);if(fx!fy){if(fxfy) swap(fx,fy);fa[fy]fx;z--;k.xa[i].u;k.ya[i].v;}}return;
}
void Solve(knode l,knode r){knode mid;mid.k1fabs(r.y-l.y);mid.k2fabs(r.x-l.x);Get_Tree(mid);if(l.ymid.y||l.yr.y||(l.x-r.x)/(l.y-r.y)(l.x-mid.x)/(l.y-mid.y))return;Solve(l,mid);k[tot]mid;Solve(mid,r);
}
int main()
{scanf(%d%d%d,n,m,q);for(int i1;im;i)scanf(%d%d%lf%lf,a[i].x,a[i].y,a[i].u,a[i].v);head.k11;tail.k21;Get_Tree(head);Get_Tree(tail);k[tot1]head;Solve(head,tail);k[tot]tail;while(q--){scanf(%lf%lf,k1,k2);int l1,rtot;double ans1e18;while(lr){if(r-l2)break;int mid1l(r-l1)/3,mid2l(r-l1)/3*2;if(k[mid1].x*k1k[mid1].y*k2k[mid2].x*k1k[mid2].y*k2) rmid2;else lmid1;}for(int il;ir;i)ansmin(k[i].x*k1k[i].y*k2,ans);printf(%.3lf\n,ans);}
}