题意:给一张n个点m条边的连通图,每条边(ai,bi)有一个权值wi和费用ci,

表示这条边每降低1的权值需要ci的花费。现在一共有S费用可以用来降低某些边的权值

(可以降到负数),求图中的一棵权值和最小的生成树并输出方案

显然是找到一条边然后将这条边减到最小

先跑一边最小生成树,找到树上最小的一点,然后在枚举其他的边,

加上这条边会产生一个环,所以需要删除这个环上面权值最大的边

这个通过类似于LCA倍增的手法做到,

 #include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#define pi acos(-1.0)
#define eps 1e-6
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a,b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define f(a) a*a
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)+
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define FIN freopen("data.txt","r",stdin)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) x&-x
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int mod = 1e9 + ;
const int maxn = 2e5 + ;
const int INF = 0x3f3f3f3f;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
int n, m, c[maxn], w[maxn], fa[maxn], vis[maxn];
int dep[maxn], p[maxn][], maxx[maxn][];
struct Edge {
int u, v, w, id;
} edge[maxn];
int cmp ( Edge a, Edge b ) {
return a.w < b.w;
}
struct xxx {
int v, id;
xxx ( int v, int id ) : v ( v ), id ( id ) {}
};
vector<xxx>mp[maxn];
int Find ( int x ) {
return fa[x] == x ? x : fa[x] = Find ( fa[x] );
}
void dfs ( int u, int f, int id ) {
dep[u] = dep[f] + , p[u][] = f, maxx[u][] = id;
for ( int i = ; i <= ; i++ ) {
if ( dep[u] - ( << i ) <= ) break;
int v = p[u][i - ];
p[u][i] = p[v][i - ];
if ( w[maxx[u][i - ]] < w[maxx[v][i - ]] ) maxx[u][i] = maxx[v][i - ];
else maxx[u][i] = maxx[u][i - ];
}
for ( int i = ; i < mp[u].size() ; i++ ) {
int v = mp[u][i].v, id = mp[u][i].id;
if ( v != f ) dfs ( v, u, id );
}
}
int get_max ( int x, int y ) {
if ( dep[x] < dep[y] ) swap ( x, y );
int temp = , ans = ;
for ( int i = ; i >= ; i-- ) {
if ( dep[x] - ( << i ) >= dep[y] ) {
if ( w[maxx[x][i]] > temp ) ans = maxx[x][i], temp = w[ans];
x = p[x][i];
}
}
if ( x == y ) return ans;
for ( int i = ; i >= ; i-- ) {
if ( dep[x] - ( << i ) > && p[x][i] != p[y][i] ) {
if ( w[maxx[x][i]] > temp ) ans = maxx[x][i], temp = w[ans];
if ( w[maxx[y][i]] > temp ) ans = maxx[y][i], temp = w[ans];
x = p[x][i], y = p[y][i];
if ( x == y ) break;
}
}
if ( w[maxx[x][]] > temp ) ans = maxx[x][], temp = w[ans];
if ( w[maxx[y][]] > temp ) ans = maxx[y][], temp = w[ans];
return ans;
}
int main() {
sff ( n, m );
for ( int i = ; i <= m ; i++ ) sf ( w[i] );
for ( int i = ; i <= m ; i++ ) sf ( c[i] );
for ( int i = ; i <= m ; i++ ) {
sff ( edge[i].u, edge[i].v );
edge[i].w = w[i], edge[i].id = i;
}
sort ( edge + , edge + + m, cmp );
LL sum = , s, minn = INF, idx = , k = ;
scanf ( "%lld", &s );
for ( int i = ; i <= n ; i++ ) fa[i] = i;
for ( int i = ; i <= m ; i++ ) {
int nx = Find ( edge[i].v ), ny = Find ( edge[i].u );
if ( nx == ny ) continue;
fa[nx] = ny;
sum += edge[i].w;
vis[edge[i].id] = , k++;
if ( c[edge[i].id] < minn ) idx = edge[i].id, minn = c[edge[i].id];
mp[edge[i].u].push_back ( xxx ( edge[i].v, edge[i].id ) );
mp[edge[i].v].push_back ( xxx ( edge[i].u, edge[i].id ) );
if ( k == n - ) break;
}
LL ans = sum - s / minn;
dep[] = ;
dfs ( , , );
int del = ;
for ( int i = ; i <= m ; i++ ) {
if ( vis[edge[i].id] ) continue;
int cnt = get_max ( edge[i].u, edge[i].v );
if ( cnt == ) continue;
LL temp = sum - w[cnt] + w[edge[i].id] - s / c[edge[i].id];
if ( temp < ans ) ans = temp, idx = edge[i].id, del = cnt;
}
if ( del ) vis[del] = , vis[idx] = ;
printf ( "%lld\n", ans );
w[idx] -= s / c[idx];
for ( int i = ; i <= m ; i++ ) if ( vis[i] ) printf ( "%d %d\n", i, w[i] );
return ;
}

Drivers Dissatisfaction 最小生成树+LCA的更多相关文章

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

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

  2. Drivers Dissatisfaction

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

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

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

  4. 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 ...

  5. 【codeforces 733F】 Drivers Dissatisfaction

    http://codeforces.com/problemset/problem/733/F (题目链接) 题意 给出一张n个点的无向图,每一条变有两个特征值:${w,c}$:分别表示这条边的权值为$ ...

  6. bzoj3732: Network--kruskal最小生成树+LCA

    这是一道写起来比较顺手的题目 没有各种奇怪的细节,基本就是Kruskal和倍增LCA的模板.. 题目大意:对于一个无向带权图,询问两点之间一条路,使得这条路上的最长边最小,输出最小最长边的的值 那么既 ...

  7. Codeforces 733F Drivers Dissatisfaction

    题意:有n个点,m条边,每条边有不满意度w[i],以及减小一个不满意度代价c[i],问给你s元用来减少代价,找到一个总不满意度最小的生成树,保证有解.(减少后的不满意度可以为负数)思路:显然所有的钱都 ...

  8. 【最小生成树+LCA】Imperial roads

    http://codeforces.com/gym/101889 I 先跑一遍最小生成树,把经过的边和答案记录下来 对于每个询问的边,显然如果处于MST中,答案不变 如果不在MST中,假设这条边连上了 ...

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

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

随机推荐

  1. CSP201512-2:消除类游戏

    引言:CSP(http://www.cspro.org/lead/application/ccf/login.jsp)是由中国计算机学会(CCF)发起的"计算机职业资格认证"考试, ...

  2. 高可用Kubernetes集群-2. ca证书与秘钥

    四.CA证书与秘钥 kubernetes集群安全访问有两种方式:"基于CA签名的双向数字证书认证"与"基于BASE或TOKEN的简单认证",生产环境推荐使用&q ...

  3. PHP开发中常见的漏洞及防范

    PHP开发中常见的漏洞及防范 对于PHP的漏洞,目前常见的漏洞有五种.分别是Session文件漏洞.SQL注入漏洞.脚本命令执行漏洞.全局变量漏洞和文件漏洞.这里分别对这些漏洞进行简要的介绍和防范. ...

  4. ecshop以及一些需要注意的

    Deprecated: Assigning the return value of new by reference is deprecated in 定位到出错的那一行: $this->_ol ...

  5. Python学习 - 入门篇2(更新中)

    前言 学习渠道:慕课网:Python进阶 记录原因:我只是想边上课边做笔记而已,呵呵哒 食用提示:教程环境基于Python 2.x,有些内容在Python 3.x中已经改变 函数式编程 定义:一种抽象 ...

  6. android入门 — ProgressDialog/DatePickerDialog/TimePickerDialog

    这三个Dialog都是AlertDialog的子类. ①DatePickerDialog 1.创建DatePickerDialog的实例: 2.通过Calendar类获得系统时间: 3.通过DateP ...

  7. lintcode-401-排序矩阵中的从小到大第k个数

    401-排序矩阵中的从小到大第k个数 在一个排序矩阵中找从小到大的第 k 个整数. 排序矩阵的定义为:每一行递增,每一列也递增. 样例 给出 k = 4 和一个排序矩阵: [ [1 ,5 ,7], [ ...

  8. Laravel 框架集成 UEditor 编辑器的方法

    ㈠. 背景 在项目开发的过程中,免不了使用修改功能,而富文本编辑器是极为方便的一种推荐,当然,个人认为 MarkDown 更为简单,但是感觉暂时只适合程序猿    此文介绍如何在 Laravel5.5 ...

  9. c# AOP 文章地址

    AOP:aspect oriented programing 面向切面编程.大概就是在程序的指定地方,可以做拦截然后插入执行指定的一段程序,这种模式在写日志,权限检查等操作很有用,这些操作都是固定的处 ...

  10. HTTP协议 结构,get post 区别(阿里面试)

    如果需要想了解相关的TCP的协议结构,底层架构,以及每次面试必问的三次握手,四次挥手可以 参考:TCP协议详解7层和4层解析(美团面试,阿里面试) 尤其是三次握手,四次挥手 具体发送的报文和状态都要掌 ...