题意:给一张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. 【python 2.7】python读取json数据存入MySQL

    同上一篇,只是适配 CentOS+ python 2.7 #python 2.7 # -*- coding:utf-8 -*- __author__ = 'BH8ANK' import json im ...

  2. Just a Hook:线段树+区间修改

    E - Just a Hook In the game of DotA, Pudge’s meat hook is actually the most horrible thing for most ...

  3. Action Required: Listings Deactivated for Potential Pricing Error

    Dear Seller, We are contacting you because we have detected potential pricing errors in your Amazon. ...

  4. 安装好Oracle Client以后没有tnsnames.ora文件

    安装好Oracle Client以后没有tnsnames.ora文件 安装完Oracle Client以后,发现相应目录中没有tnsnames.ora文件,其实只要手动建立一个就可以了.在 oracl ...

  5. pyextend库-unpack列表集合字符串解包函数

    pyextend - python extend lib unpack (iterable, count, fill=None) 参数: iterable: 实现 __iter__的可迭代对象, 如 ...

  6. AOP:spring 的Annotation配置

    1.文件目录: 2.实体类 package com.wangcf.po; public class User { private int id; private String name; privat ...

  7. c# dataGridView排序

    一.对阿拉伯数字进行自定义排序: 简单有效方法: 1.该列的sortmode属性为auto...(一般默认) 2.比如首列序号,添加该列数据的时候直接添加int即可.切忌不要用string. obje ...

  8. Android开发第二阶段(1)

    今天:总结第一阶段的冲刺成果,第一阶段就是主要是学习andriod开发,参考文件有<黑马教学视频><Mars教学视频>...结果在看的过程遇到很多问题特别是对java的一些理解 ...

  9. 《高性能JavaScript》学习笔记——日更中

    ------------------2016-7-20更------------------ 最近在看<高性能JavaScript>一书,里面当中,有讲很多提高js性能的书,正在看的过程中 ...

  10. Jmeter 快速入门--简单的http压测

    1.添加线程组 打开jmeter主窗口后,选择左侧树形结构里的"测试计划",然后右键选择添加,选择"threads(users)",选择"线程组&qu ...