题意:给出一个图,每条边有权值和花费c,每次花费c能使的权值-1。给出一个预算,求减完权值后的一个最小生成树。

思路:感谢CC大神

有这样一个结论:最佳方案里必定存在一种,预算全部花费全部分配在一条边上。证明显然,对于任意一组解,都可以在内部再分配预算使总费用更小或不变。

于是先求出原图的最小生成树,枚举每条边。

对于在生成树中的,判断使这条边减费是否更优。

不在生成树上的,找出树上从x[i]到y[i]的路径(唯一)上a[i]最大的边,判断删除那条边并加入减费后的(x[i],y[i])是否更优。

 type yjs=record
a:longint;
s:int64;
end;
var f,q,g:array[..,..]of longint;
head,vet,next,len,num,a,b,c,x,y,dep,fa,inq,ya,yb:array[..]of longint;
hth,mst,s:int64;
tot,n,m,i,del,k,tx,ty:longint;
t:yjs; procedure swap(var x,y:longint);
var t:longint;
begin
t:=x; x:=y; y:=t;
end; procedure qsort(l,r:longint);
var i,j,mid:longint;
begin
i:=l; j:=r; mid:=a[(l+r)>>];
repeat
while mid>a[i] do inc(i);
while mid<a[j] do dec(j);
if i<=j then
begin
swap(a[i],a[j]); swap(b[i],b[j]); swap(c[i],c[j]);
swap(x[i],x[j]); swap(y[i],y[j]);
inc(i); dec(j);
end;
until i>j;
if l<j then qsort(l,j);
if i<r then qsort(i,r);
end; procedure add(a,b,c,d:longint);
begin
inc(tot);
next[tot]:=head[a];
vet[tot]:=b;
len[tot]:=c;
num[tot]:=d;
head[a]:=tot;
end; function lca(x,y:longint):longint;
var i,d:longint;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
for i:= to do
if d and (<<i)> then x:=q[x,i];
for i:= downto do
if q[x,i]<>q[y,i] then
begin
x:=q[x,i]; y:=q[y,i];
end;
if x=y then exit(x);
exit(q[x,]);
end; function clac(x,y:longint):yjs;
var i,d:longint;
cc:yjs;
begin
if dep[x]<dep[y] then swap(x,y);
d:=dep[x]-dep[y];
cc.a:=; cc.s:=-maxlongint;
for i:= downto do
if d and (<<i)> then
begin
if f[x,i]>cc.s then
begin
cc.a:=g[x,i];
cc.s:=f[x,i];
end;
x:=q[x,i];
end;
exit(cc);
end; function ask(x,y:longint):yjs;
var t:longint;
t1,t2:yjs;
begin
t:=lca(x,y);
t1:=clac(x,t);
t2:=clac(y,t);
if t1.s>t2.s then exit(t1);
exit(t2);
end; function find(k:longint):longint;
begin
if fa[k]<>k then fa[k]:=find(fa[k]);
find:=fa[k];
end; procedure dfs(u,pre:longint);
var e,v,i:longint;
begin
for i:= to do
begin
if dep[u]<(<<i) then break;
q[u,i]:=q[q[u,i-],i-];
if f[u,i-]<f[q[u,i-],i-] then
begin
f[u,i]:=f[q[u,i-],i-];
g[u,i]:=g[q[u,i-],i-];
end
else
begin
f[u,i]:=f[u,i-];
g[u,i]:=g[u,i-];
end;
end;
e:=head[u];
while e<> do
begin
v:=vet[e];
if v<>pre then
begin
dep[v]:=dep[u]+;
f[v,]:=len[e];
q[v,]:=u;
g[v,]:=num[e];
dfs(v,u);
end;
e:=next[e];
end;
end; begin readln(n,m);
for i:= to m do read(a[i]);
for i:= to m do read(b[i]);
for i:= to m do c[i]:=i;
for i:= to m do readln(x[i],y[i]);
readln(s);
ya:=a; yb:=b;
qsort(,m);
for i:= to n do fa[i]:=i;
for i:= to m do
begin
tx:=find(x[i]); ty:=find(y[i]);
if tx<>ty then
begin
fa[ty]:=tx;
hth:=hth+a[i];
inq[c[i]]:=;
add(x[i],y[i],a[i],c[i]);
add(y[i],x[i],a[i],c[i]);
end;
end;
dfs(,-);
mst:=hth;
for i:= to m do
if inq[c[i]]= then
begin
if mst-s div b[i]<hth then
begin
hth:=mst-s div b[i];
k:=c[i];
end;
end
else
begin
t:=ask(x[i],y[i]);
if mst-ya[t.a]+a[i]-s div b[i]<hth then
begin
hth:=mst-ya[t.a]+a[i]-s div b[i];
k:=c[i];
del:=t.a;
end;
end;
writeln(hth);
for i:= to m do
begin
if i=del then continue;
if i=k then begin writeln(i,' ',ya[i]-s div yb[i]); continue; end;
if inq[i]= then writeln(i,' ',ya[i]);
end; end.

【CF733F】Drivers Dissatisfaction(最小瓶颈生成树,倍增)的更多相关文章

  1. 【UVA 11354】 Bond (最小瓶颈生成树、树上倍增)

    [题意] n个点m条边的图 q次询问 找到一条从s到t的一条边 使所有边的最大危险系数最小 InputThere will be at most 5 cases in the input file.T ...

  2. 【最小瓶颈生成树】【最小生成树】【kruscal】bzoj1083 [SCOI2005]繁忙的都市

    本意是求最小瓶颈生成树,但是我们可以证明:最小生成树也是最小瓶颈生成树(其实我不会).数据范围很小,暴力kruscal即可. #include<cstdio> #include<al ...

  3. POJ 1861 ——Network——————【最小瓶颈生成树】

    Network Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 15268   Accepted: 5987   Specia ...

  4. 【bzoj2429】[HAOI2006]聪明的猴子(图论--最小瓶颈生成树 模版题)

    题意:有M只猴子,他们的最大跳跃距离为Ai.树林中有N棵树露出了水面,给出了它们的坐标.问有多少只猴子能在这个地区露出水面的所有树冠上觅食. 解法:由于要尽量多的猴子能到达所有树冠,便用Kruskal ...

  5. UVA 11354 Bond(最小瓶颈路+倍增)

    题意:问图上任意两点(u,v)之间的路径上,所经过的最大边权最小为多少? 求最小瓶颈路,既是求最小生成树.因为要处理多组询问,所以需要用倍增加速. 先处理出最小生成树,prim的时间复杂度为O(n*n ...

  6. CF733F Drivers Dissatisfaction【链剖】【最小生成树应用】

    F. Drivers Dissatisfaction time limit per test 4 seconds memory limit per test 256 megabytes input s ...

  7. luogu p2330[SCOI05] 繁忙的都市——瓶颈生成树

    P2330 05四川 繁忙的都市 题目描述 城市C是一个非常繁忙的大都市,城市中的道路十分的拥挤,于是市长决定对其中的道路进行改造.城市C的道路是这样分布的:城市中有n个交叉路口,有些交叉路口之间有道 ...

  8. 瓶颈生成树与最小生成树 POJ 2395 Out of Hay

    百度百科:瓶颈生成树 瓶颈生成树 :无向图G的一颗瓶颈生成树是这样的一颗生成树,它最大的边权值在G的所有生成树中是最小的.瓶颈生成树的值为T中最大权值边的权. 无向图的最小生成树一定是瓶颈生成树,但瓶 ...

  9. POJ 2395 Out of Hay 草荒 (MST,Kruscal,最小瓶颈树)

    题意:Bessie要从牧场1到达各大牧场去,他从不关心他要走多远,他只关心他的水袋够不够水,他可以在任意牧场补给水,问他走完各大牧场,最多的一次需要多少带多少单位的水? 思路:其实就是要让所带的水尽量 ...

随机推荐

  1. C#基于联通短信Sgip协议构建短信网关程序

    此软件基于中国联通Sgip协议程序接口,适合在中国联通申请了短信发送端口的公司使用.短信群发已经成为现在软件系统.网络营销等必不可少的应用工具.可应用在短信验证.信息群发.游戏虚拟商品购买.事件提醒. ...

  2. 【SAM】loj#6401. 字符串

    网上有篇题解写的是线段树合并维护求值? 题目描述 有一个只包含小写字母,长度为 $n$ 的字符串 $S$ .有一些字母是好的,剩下的是坏的. 定义一个子串 $S_{l\ldots r}$是好的,当且仅 ...

  3. python面向对象之抽象工厂设计模式

    class truck: def use(self): return "拉货" def __str__(self): return "大卡车" class mi ...

  4. Bootstrap 模态框 禁止点击空白关闭模态框事件

    在模态框的div中加上 aria-hidden="true" data-backdrop="static" <div class="modal ...

  5. kali下安装中文输入法

    参考网址:https://blog.csdn.net/qq_37367124/article/details/79229739 更性源 vim /etc/apt/source.list 设置更新源 更 ...

  6. Python基础——字典(dict)

    由键-值对构建的集合. 创建 dic1={} type(dic1) dic2=dict() type(dic2) 初始化 dic2={'hello':123,'world':456,'python': ...

  7. numpy 三个点的使用[...]

    numpy [...]语法简单使用 Python numpy中切片功能与列表切片类似,但功能更加强大 本文主讲numpy中[...]的简单使用,后续工作继续补充. import numpy >& ...

  8. cf 1016C

    C. Vasya And The Mushrooms time limit per test 2 seconds memory limit per test 256 megabytes input s ...

  9. mac配置启动mongodb

    1.新建文件夹,用于存放数据库文件.建议放在自己用户名的文件夹下,不需要sudo会方便很多. 在Users的自己用户名环境下: mkdir [文件夹名] 2.转到mongodb的Bin目录,执行mon ...

  10. day19-IO多路复用

    1.I/O多路复用指:通过一种机制,可监听多个描述符(soket对象)(文件句柄),一旦某个描述符发送编号(一般指读就绪或写就绪),能够通知程序进行相应的读写操作. 2.I/O多路复用方式:selec ...