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. 【题解】 bzoj2115: [Wc2011] Xor (线性基+dfs)

    bzoj2115,戳我戳我 Solution: 看得题解(逃,我太菜了,想不出这种做法 那么丢个链接 Attention: 板子别写错了 又写错了这次 \(long long\)是左移63位,多了会溢 ...

  2. vue 新增时清除表单验证注意事项

    // 清除表单校验的提示 if (this.$refs['XXX']) { // 延时执行 this.$nextTick(function () { this.$refs['XXX'].clearVa ...

  3. IO之间的比较

    在高性能的IO体系设计中,有几个名词概念常常会使我们感到迷惑不解.具体如下: 序号 问题 1 什么是同步? 2 什么是异步? 3 什么是阻塞? 4 什么是非阻塞? 5 什么是同步阻塞? 6 什么是同步 ...

  4. [Java] Servlet工作原理之二:Session与Cookie

    (未完成) 一.Cookie与Session的使用简介 1 Cookie Cookie 用于记录用户在一段时间内的行为,它有两个版本:Version 0 和 Version 1,分别对应两种响应头 S ...

  5. OpenStack API部分高可用配置(一)

    一.概况与原理  SHAPE  \* MERGEFORMAT 1)所需要的配置组件有:pacemaker+corosync+HAProxy 2)主要原理:HAProxy作为负载均衡器,将对openst ...

  6. MySql与对应的Java的时间类型

    MySql的时间类型有          Java中与之对应的时间类型date                                           java.sql.Date Date ...

  7. Python配置tab自动补全功能

    # cat tab.py #!/usr/bin/python # python tab file import sys import readline import rlcompleter impor ...

  8. elementUI 表格分页后台排序记录

    表格代码 <div class="m-table"> <el-table :data="logs" style="width: 10 ...

  9. linux的lemon安装示范

    \(First\): 1. 准备好 lemon原文件 2. 解压压缩包(名字必须是lemon) 第二步:找到readme.md这个文件 第三步:了解一下安装指南 第四步:打开终端 注意:源代码目录就是 ...

  10. PyQT5 No module named ‘PyQt5.QtWebEngineWidgets’

    PyQT5查找不到模块QtWebEngineWidgets pip install pyqt5==5.10.1 或 安装64位的Pyhon解释器