codeforces 733F. Drivers Dissatisfaction
来源:互联网 发布:淘宝一千零一夜从哪看 编辑:程序博客网 时间:2024/06/06 03:27
题目链接:http://codeforces.com/contest/733/problem/F
题目大意:给一张n个点m条边的连通图,每条边(ai,bi)有一个权值wi和费用ci,表示这条边每降低1的权值需要ci的花费。现在一共有S费用可以用来降低某些边的权值(可以降到负数),求图中的一棵权值和最小的生成树并输出方案。
数据范围:2 ≤ n ≤ 2·10^5, n - 1 ≤ m ≤ 2·10^5, 1 ≤ wi, ci, S ≤ 10^9
题解:感觉我已经在水题的道路上一去不复返了hhhh。由于wi可以是负数,因此对于一棵生成树,我们只要把S全部用在ci最小的边即可。求出原图中的一棵最小生成树以及树中ci最小的边,计算出当前权值和。枚举每条不在生成树上的边 j (cj < ci),用lca求出aj到bj路径上w最大的边,用wj替换它然后计算出权值和,如果比答案小就更新答案。最后输出方案即可。
时间复杂度O(nlogn+mlogn)
代码如下:
#include <algorithm>#include <cstdio>const int N=200005;int f[N][20],g[N][20],fa[N],w[N],c[N],a[N],b[N],id[N],fi[N], to[N*2],ne[N*2],v[N*2],dep[N],u[N],n,m,tot,mn;long long sum,ans;bool cmp(int x,int y){return w[x]<w[y];}int find(int x){return fa[x]==x?x:fa[x]=find(fa[x]);}void add(int x,int y,int z){ to[++tot]=y;v[tot]=z;ne[tot]=fi[x];fi[x]=tot;}void dfs(int x){ dep[x]=dep[f[x][0]]+1; for (int i=f[x][0],j=0;f[i][j];i=f[i][j++]){ f[x][j+1]=f[i][j]; if (w[g[i][j]]>w[g[x][j]]) g[x][j+1]=g[i][j]; else g[x][j+1]=g[x][j]; } for (int i=fi[x];i;i=ne[i]) if (to[i]!=f[x][0]){ f[to[i]][0]=x; g[to[i]][0]=v[i]; dfs(to[i]); }}int lca(int x,int y){ int z=0; if (dep[x]<dep[y]) std::swap(x,y); for (int i=17;dep[x]>dep[y];x=f[x][i]){ for (;i && dep[f[x][i]]<dep[y];i--); if (w[g[x][i]]>w[z]) z=g[x][i]; } for (int i=17;x!=y;x=f[x][i],y=f[y][i]){ for (;i && f[x][i]==f[y][i];i--); if (w[g[x][i]]>w[z]) z=g[x][i]; if (w[g[y][i]]>w[z]) z=g[y][i]; } return z;}int main(){ scanf("%d%d\n",&n,&m); for (int i=1;i<=m;i++) scanf("%d",&w[i]); for (int i=1;i<=m;i++) scanf("%d",&c[i]); for (int i=1;i<=m;i++) scanf("%d%d",&a[i],&b[i]); for (int i=1;i<=m;i++) id[i]=i; std::sort(id+1,id+m+1,cmp); for (int i=1;i<=n;i++) fa[i]=i; sum=0;c[mn=0]=2000000000; for (int i=1,j=id[1];i<=m;j=id[++i]) if (find(a[j])!=find(b[j])){ fa[find(a[j])]=find(b[j]); sum+=w[j];u[j]=1; add(a[j],b[j],j); add(b[j],a[j],j); if (c[j]<c[mn]) mn=j; } long long S; scanf("%I64d\n",&S); ans=sum-S/c[mn]; dfs(1); int minc=c[mn]; for (int i=1;i<=m;i++) if (c[i]<minc){ int x=lca(a[i],b[i]); long long cur=sum+w[i]-w[x]-S/c[i]; if (cur<ans) ans=cur,mn=i; } printf("%I64d\n",ans); w[mn]-=S/c[mn];u[lca(a[mn],b[mn])]=0;u[mn]=1; for (int i=1;i<=m;i++) if (u[i]) printf("%d %d\n",i,w[i]);}
0 0
- codeforces 733F. Drivers Dissatisfaction
- codeforces #378F(733.F) Drivers Dissatisfaction
- 【Codeforces 733F】 Drivers Dissatisfaction 【MST+bianry lifting】
- codeforces 733 F. Drivers Dissatisfaction(最小生成树+lca+倍增去环)
- CodeForces 733 F.Drivers Dissatisfaction(最小生成树-Kruskal+在线倍增法)
- Codeforces Round #378 (Div. 2) F. Drivers Dissatisfaction
- 树链剖分,最小生成树(Drivers Dissatisfaction,cf 733F)
- codeforces 733F (树链剖分 RMQ)
- Codeforces 659F F
- Codeforces 234 F. Fence
- 【Codeforces 500F】Dp
- codeforces 234F - Fence
- F-Logo Turtle codeforces
- 【CODEFORCES】 F. Ant colony
- Codeforces 567F
- CodeForces 241F Race
- Codeforces 611F 思维
- Codeforces 542F 构造
- 单身狗
- maven 聚合和继承
- spring data jpa初学心得
- Python学习备忘录
- Java 泛型相关
- codeforces 733F. Drivers Dissatisfaction
- 11月8日 课程设计幸运抽奖系统
- [Usaco07Oct] Bessie's Secret Pasture
- 哈密顿绕行世界问题
- 静态页面的翻页
- 一、Django框架创建
- 代理模式通用模板实现
- C++ 中的单例模式
- NOIP2014无线网络发射选址【Pascal】