CF733F Drivers Dissatisfaction(次小生成树)

【问题描述】

给出一张 n 个点 m 条边的无向图,每条边(ai,bi)有一个权值 wi 和费用 ci,表示这条边 每降低 1 的权值需要 ci 的花费。现在一共有 S 费用可以用来降低某些边的权值(可以降到 负数),求图中的一棵权值和最小的生成树并输出方案。

【输入描述】

第一行两个整数 n,m。 第二行 m 个整数 wi,表示每条边的权值。 第三行 m 个整数 ci,表示这条边每降低 1 的权值需要 ci 的花费 接下来 m 行,每行两个整数 ai,bi,表示 ai 到 bi 有边 最后一行一个整数 S

【输出描述】

求在代价不超过 S 的情况下,最终图中最小生成树权值和最小是多少。 输出最终在最小生成树中的边的编号,以及每条边的权值。

分析

首先我们最后一定是把所有的花费用在一条边上面。
假设我们已经求出了最小生成树, c i c_i ci 最小值为 m i n c minc minc,那么花费一定都是在这条边上。
现在我们枚举不在树上的边,会和原来那棵树形成一个环,由于这条边本来不在最小生成树上,所以如果这条边最终在最小生成树上,一定是把所有花费都用在这条边上了,然后取代了环上最大的边。然后就倍增求环上最大边的编号和值就可以了,每次如果替换后答案更小,就记录换上的边和环上最大边(要取代的边)就可以了。

代码如下

#include <bits/stdc++.h>
#define N 200005
#define inf 2147483647
#define LL long long
using namespace std;
struct node{
   
	int a, b, c, w, i, n;
	bool operator < (const node & A) const{
   
		if(w != A.w) return w < A.w;
		return c < A.c;
	}
}d[N * 2], e[N];
int h[N], f[N], vis[N], dep[N], val[N][20], st[N][20], fa[N], C[N], W[N], cnt, minc = inf;
LL ans, sum, ans1, z = 1;
int p[2], edg[N][20];
void cr(int a, int b, int c, int i){
   
	d[++cnt].a = a; d[cnt].b = b; d[cnt].c = c; d[cnt].i = i; d[cnt].n = h[a]; h[a] = cnt;
}
int 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值