F - Drivers Dissatisfaction

题目大意:给你n个点,m条边,每个边都有一个权重w,每条边也有一个c表示,消耗c元可以把这条边的权重减1,求最多消耗s元的最小生成树。

思路:因为一条边的权重没有下限所以s元肯定是用在一条边上的。 那么我们先跑一个最小生成树,把这棵最小生成树建出来,然后我们枚举用了

s元之后的边,如果这条边不在树上那么加上这条边之后肯定形成了一个环,最优的方案肯定是删掉这个环中权值最大的边再次变成一棵树。

对于边(u,v)来说,如果把这条边加上,那么删掉的边肯定在,u到 lca(u,v) 和 v到 lca(u,v)中的权值最大的那条边。 可以用倍增快速找边,就能解决

这个问题啦。  码起来好麻烦啊,借鉴了某个学长的代码。。

 #include<bits/stdc++.h>
#define fi first
#define se second
#define mk make_pair
#define ll long long
#define pll pair<ll,ll>
#define pil pair<int,ll>
#define pli pair<ll,int>
#define pii pair<int,int>
#define read(x) scanf("%d",&x)
#define sread(x) scanf("%s",x)
#define dread(x) scanf("%lf",&x)
#define lread(x) scanf("%lld",&x)
using namespace std; const int N=2e5+;
const int M=2e6+;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int mod=1e9+; int n,m,tot,s,fa[N],depth[N],nx[N][],mx[N][]; struct node
{
int u,v,w,c,id;
bool operator < (const node &rhs)const
{
return w<rhs.w;
}
}e[N<<]; bool cmp(node a,node b){
return a.id<b.id;
}
vector<pii> edge[N];
map<int,int> result; int Find(int x) {
return x==fa[x]? x : fa[x]=Find(fa[x]);
} ll kruscal()
{
ll ans=;
for(int i=;i<=n;i++)
fa[i]=i; sort(e,e+m); for(int i=;i<m;i++)
{
int u=e[i].u,v=e[i].v,w=e[i].w;
int nx_u=Find(u);
int nx_v=Find(v);
if(nx_u!=nx_v)
{
edge[u].push_back(mk(v,e[i].id));
edge[v].push_back(mk(u,e[i].id)); fa[nx_u]=nx_v;
ans+=w;
result[e[i].id]=w;
}
} sort(e,e+m,cmp); return ans;
} int getMxId(int a,int b)
{
if(a==-) return b;
if(b==-) return a;
return e[a].w>e[b].w? a : b;
}
void dfs(int u,int pre)
{
nx[u][]=pre;
for(int i=;i<;i++)
{
if(nx[u][i-]!=-)
{
nx[u][i]=nx[nx[u][i-]][i-];
mx[u][i]=getMxId(mx[u][i-],mx[nx[u][i-]][i-]);
}
else
nx[u][i]=mx[u][i]=-;
} for(auto t : edge[u])
{
int v=t.first;
if(v==pre)
continue;
depth[v]=depth[u]+;
mx[v][]=t.second; dfs(v,u);
}
} int getLca(int a,int b)
{
if(depth[a]<depth[b])
swap(a,b);
for(int i=;i<;i++)
if(depth[a]-depth[b]>>i & )
a=nx[a][i]; if(a==b) return a;
for(int i=;i>=;i--)
if(nx[a][i]!=nx[b][i])
a=nx[a][i],b=nx[b][i]; return nx[a][];
} int getMxIdPath(int a,int b)
{
int lca=getLca(a,b);
int ret=-;
for(int i=;i>=;i--)
{
if(nx[a][i]!=- && depth[nx[a][i]]>=depth[lca])
{
ret=getMxId(ret,mx[a][i]);
a=nx[a][i];
}
if(nx[b][i]!=- && depth[nx[b][i]]>=depth[lca])
{
ret=getMxId(ret,mx[b][i]);
b=nx[b][i];
}
}
return ret;
} int main()
{
read(n); read(m); for(int i=;i<m;i++)
read(e[i].w); for(int i=;i<m;i++)
read(e[i].c); for(int i=;i<m;i++)
{
read(e[i].u);
read(e[i].v);
e[i].id=i;
} read(s); ll cost=kruscal(); dfs(,-); ll ans=cost, p=; for(int id=;id<m;id++)
{
int big=getMxIdPath(e[id].u,e[id].v);
ll tmp=cost-e[big].w+e[id].w-s/e[id].c;
if(tmp<ans)
ans=tmp,p=id;
} printf("%lld\n",ans);
result.erase(getMxIdPath(e[p].u,e[p].v));
result[p]=e[p].w-s/e[p].c; for(auto t: result)
printf("%d %d\n",t.first+,t.second); return ;
}
/*
*/

Codeforces Round #378 (Div. 2) F - Drivers Dissatisfaction的更多相关文章

  1. Codeforces Round #378 (Div. 2)F - Drivers Dissatisfaction GNU

    http://codeforces.com/contest/733/problem/F 题意:给你一些城市和一些路,每条路有不满意程度和每减少一点不满意程度的花费,给出最大花费,要求找出花费小于s的最 ...

  2. Codeforces Round #378 (Div. 2)F

    题目:一个带权连通无向图,给第i条边权值减1需要花费ci元,你一共有S元,求最小生成树. 容易得出钱全部花在一条边上是最优的. 我们先做一遍最小生成树. 然后我们枚举减哪一条边. 如果这条边是树上的, ...

  3. codeforce 378 div 2 F —— Drivers Dissatisfaction (最小生成树,LCA,倍增)

    官方题解: If you choose any n - 1 roads then price of reducing overall dissatisfaction is equal to min(c ...

  4. Codeforces Round #485 (Div. 2) F. AND Graph

    Codeforces Round #485 (Div. 2) F. AND Graph 题目连接: http://codeforces.com/contest/987/problem/F Descri ...

  5. Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

    Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/co ...

  6. Codeforces Round #501 (Div. 3) F. Bracket Substring

    题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60 ...

  7. Codeforces Round #499 (Div. 1) F. Tree

    Codeforces Round #499 (Div. 1) F. Tree 题目链接 \(\rm CodeForces\):https://codeforces.com/contest/1010/p ...

  8. Codeforces Round #378 (Div. 2) D题(data structure)解题报告

    题目地址 先简单的总结一下这次CF,前两道题非常的水,可是第一题又是因为自己想的不够周到而被Hack了一次(或许也应该感谢这个hack我的人,使我没有最后在赛后测试中WA).做到C题时看到题目情况非常 ...

  9. Codeforces Round #376 (Div. 2)F. Video Cards(前缀和)

    题目链接:http://codeforces.com/contest/731/problem/F 题意:有n个数,从里面选出来一个作为第一个,然后剩下的数要满足是这个数的倍数,如果不是,只能减小为他的 ...

随机推荐

  1. 【刷题】BZOJ 3745 [Coci2015]Norma

    Description Input 第1行,一个整数N: 第2~n+1行,每行一个整数表示序列a. Output 输出答案对10^9取模后的结果. Sample Input 4 2 4 1 4 Sam ...

  2. kubernetes配置secret拉取私仓镜像

    2017.05.10 19:48* 字数 390 阅读 5216评论 0喜欢 8 对于公司内部的项目, 我们不可能使用公有开放的镜像仓库, 一般情况可能会花钱买docker私仓服务, 或者说自己在服务 ...

  3. 关闭ubuntu dash 方法

    因为ubuntu默认的sh是连接到dash的,又因为dash跟bash的不兼容所以出错了.执行时可以把sh换成bash 文件名.sh来执行.成功.dash是什么东西,查了一下,应该也是一种shell, ...

  4. LSTM介绍

    转自:https://blog.csdn.net/gzj_1101/article/details/79376798 LSTM网络 long short term memory,即我们所称呼的LSTM ...

  5. docker mysql authentication_string client does not support authentication 连接问题

    docker安装mysql后,本地navicat连接报错client does not support authentication 解决办法: 1. docker ps -a 查找到容器id 2.  ...

  6. php-fpm的status可以查看汇总信息和详细信息

    nginx.conf 配置文件 server { listen ; server_name localhost; index index.php index.html; root /home/tiny ...

  7. [QuickRoR]Ruby on Rails开发环境安装

    1.Setup Ruby on Rails2.Test Web App3.Create the First Web App 1.Setup Ruby on Rails1) Download rubyi ...

  8. 第5月第13天 node cnpm安装 babel

    1. https://nodejs.org/en/download/ http://www.runoob.com/react/react-install.html 2. npm install --s ...

  9. python学习之——import sys模块

    (1)sys.argv sys模块中的argv变量通过使用点号指明——sys.argv——这种方法的一个优势是这个名称不会与任何在你的程序中使用的argv变量冲突.另外,它也清晰地表明了这个名称是sy ...

  10. Android的layout_weight和weightSum

    先看一下weightSum属性的功能描述:定义weight总和的最大值.如果未指定该值,以所有子视图的layout_weight属性的累加值作为总和的最大值.把weightSum的定义搁在这里,先去看 ...