首页 > 其他分享 >CF76A gift

CF76A gift

时间:2024-04-25 13:36:21浏览次数:14  
标签:fda gift int CF76A pos 生成 最小 E2

题目简述:

给定一个有 \(n\) 个节点, \(m\) 条边的图,每条边有两个权值 \(g\) ,\(s\)。对于图中的一棵生成树,它的花费定义为 \(\max _ {i \in e}{g_i} \times valg + \max _ {i \in e}{s_i} \times vals\) ,求原图中最小花费的一棵生成树。

\(n \le 200\), \(m \le 10^5\)

Solution:

最小生成树好题。

通过题面容易联想到最小生成树,与普通的最小生成树有区别的是,这道题是有两个限制的。

首先考虑消掉一个限制,即枚举 \(maxg\),同时加入 \(g \le maxg\) 的边。

此时可以直接做一遍 \(\rm Kruskal\) 算 \(maxs\) 的最小值。

但是时间复杂度是 \(O(m^2 log n)\) 的,会爆。

建图可以通过维护指针优化到均摊 \(O(m)\),排序直接通过插入排序优化到 \(O(m)\),每次加边, 考虑去除无用状态减少 \(\rm Kruskal\) 的复杂度。

进而有一个比较好猜的结论:

  • 对于一条之前不是最小生成树上的边,即使加入一些边之后,它依旧不是最小生成树上的边。

证明如下:

考虑加入一条边 \(x\) 生成树,它必然要替换掉它两端节点到 \(\rm LCA\) 的路径上的某一条边。若它替换掉的是边 \(y\)。此时对花费的贡献是 \(s[x]-s[y]\)。如果贡献大于 \(0\),替换后会更优,否则不会。

对于刚加入的某一条边 \(x\) ,如果它不在生成树上,那么一定有 \(w[x] > \max(w[i])\) (其中 \(i\) 是路径上的边)。

加入某一条边之后,假如它替换掉了某一条边,那么通过上面的公式,显然不会使得最大值更大。

所以条件不变,不是最小生成树上的边依旧没用。

所以我们只维护原来在最小生成树的边,边的规模由 \(m\) 缩小到 \(n\)。

时间复杂度降为 \(O(nm)\)

code:

#include<bits/stdc++.h>
#define int long long 
using namespace std;

const int N = 200 + 10, M = 5e4 + 10 , INF = 9000000000000000000;
struct Edge{
	int from, to;
	int g, s;
}E[M], E2[M];
int n, m, costs, costg, Ecnt;
bool cmpE(struct Edge E1, struct Edge E2){return E1.g < E2.g;}
int fda[N];

int getfa(int x){return fda[x] = (fda[x] == x)? x : getfa(fda[x]);} 

signed main(){
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n >> m >> costg >> costs;
	int ans = INF;
	for(int i = 1; i <= m; i++)cin >> E[i].from >> E[i].to >> E[i].g >> E[i].s;
	sort(E + 1, E + m + 1, cmpE);
	for(int i = 1; i <= m; i++){
		int pos = ++Ecnt;
		while(pos > 1 &&E2[pos - 1].s > E[i].s){
			E2[pos] = E2[pos - 1];
			pos--;
		}
		E2[pos] = E[i];
		for(int j = 1; j <= n; j++)fda[j] = j;
		int newcnt = 0, cnts = 0, cntg = 0;
		for(int j = 1; j <= Ecnt; j++){
			if(getfa(E2[j].from) == getfa(E2[j].to))continue;
			fda[getfa(E2[j].from)] = getfa(E2[j].to);
			E2[++newcnt] = E2[j];
			cnts = max(cnts, E2[j].s);
			cntg = max(cntg, E2[j].g);
		}
		Ecnt = newcnt;
		if(Ecnt >= n - 1)ans = min(ans, cnts * costs + cntg * costg);
	}
	if(ans != INF)cout << ans;
	else cout << -1;
	
	return 0;
}

换了一个更好看的码风 qwq

标签:fda,gift,int,CF76A,pos,生成,最小,E2
From: https://www.cnblogs.com/little-corn/p/18157499

相关文章

  • D. Birthday Gift
    原题链接题解1.异或是01变1,11变0,或是01变1,11变1,所以或的越多(即分的组越多),结果越大2.我们令x=x+1,这样小于等于x的问题就变成了小于x的问题,这里我们采用逼近答案的方法。3.对于某一位而言,如果有奇数个元素在这一位上是1,那么不管怎么分,最后的结果肯定是1,如果是偶数,那么最后的结......
  • Birthday Gift
    我们将\(x++\),从而最终的答案一定是要小于\(x\)的,也就一定要有一位不同我们从高位到低位枚举最高的一位与\(x\)不同的位置\(i\)(也就是说,认为第\(i+1\)位到最高位都与\(x\)相同,但第\(i\)位不同)我们先考虑更高位置如何相同如果更高位置为\(0\),那么那一位必须只能有偶数个\(1\)(否......
  • E. Anna and the Valentine's Day Gift
    原题链接题解游戏规则总结一句话:安娜要尽可能删掉后导零(翻转),萨沙要尽可能保护后导零(连接),问剩余数字的位数能否达到\(m+1\)位直接模拟即可,统计每个数后导零的长度,然后按照安娜先手的规则求出能保留多少位后导零,最后判断长度code#include<bits/stdc++.h>usingnamespaces......
  • P4090 [USACO17DEC] Greedy Gift Takers P
    原题链接题解1.如果前\(7\)头牛能全部能拿到礼物,但是这前\(7\)头牛里有\(4\)头牛更新在前\(4\)的位置,请问第\(8\)头牛能否得到礼物?答案是不行,因为前\(4\)头牛会在前\(4\)的位置形成循环2.假如恰好第\(x\)头牛没有礼物,那么牛\(x\)之后的牛都得不到礼物,因为不......
  • [USACO17DEC] Greedy Gift Takers
    原题链接首先这道题的数据量1e5那么时间复杂度要保持在O(nlogn)内。先判断单调性,若k头牛拿不到礼物,那么k-1头牛也拿不到礼物,所有这题可以用二分法来做(11110000)。二分部分省略,我们直接来分析check部分(如下)。boolcheck(intk){for(inti=1;i<=n-k+1;i++)b[i]=a[i];s......
  • 初中英语优秀范文100篇-024The Best Gift I've Ever Received -我收到的最好的礼物
    PDF格式公众号回复关键字:SHCZFW024记忆树1AmongallthegiftsIhavereceived,thehand-madescarffromJudyisthebestgiftI'veeverreceived.翻译在我收到的所有礼物中,Judy亲手制作的围巾是我收到的最好的礼物简化记忆围巾句子结构这个句子是一个简单句......
  • As a project I always want to create for myself as a gift, the MVVM framework is
    IusedtowanttobuildaMVVMprojectformyself,especiallysinceIwrotemymementowriterprojectwhichisnojQuery,andthatwasverytimeconsumingandtiringtocreate.Lastyear,Ihadsomeinspiration,andreallywantedtotrytostartfreshthin......
  • QOJ # 5573. Holiday Regifting
    题面传送门感觉有点奇妙。首先一个基础的想法就是一个一个往下推,维护每个数往下推的次数,统计当前数在前面的所有数一次归零后会加几次,然后计算这个数需要前面几轮归零,这样将这些系数乘起来就是需要归零的次数了。但是现在有一个问题就是前面每个数往下推的次数可能很大,这东西存......
  • B. Buying gifts[贪心]
    Problem-1801B-Codeforces题意是需要给两个人买礼物,有n个商店,每个商店只能给一个人买,而且每个商店给两个人买的礼物的价钱也可能不同,问给两人买的礼物的最大价格之差最小是多少。我们考虑这种情况。如果当前给b买的礼物最大值为x,那么那些商店里给b礼物价格小于等于x的我们......
  • CF506E Mr. Kitayuta's Gift 思考--zhengjun
    妙妙题。首先可以有一个\(O(kn^2)\)的dp,但是显然不行。但是,发现其中的大多数转移都浪费在自环上了,所以考虑不要这个东西。这个dp一共有三种转移:左右端点一起向内移动一格;左端点或右端点单独移动;左右端点都不动。所以考虑加一维\(k\)表示走了\(k\)次转移1......