正题

题目链接:https://www.luogu.com.cn/problem/AT4437


题目大意

有nnn个点的一张有向完全图,每个点有两个点权a,ba,ba,b。连接x,yx,yx,y两个点的边权为min{ax,by}min\{a_x,b_y\}min{ax​,by​},求一条权值和最小的哈密顿回路。

1≤n≤105,1≤a,b≤1091\leq n\leq 10^5,1\leq a,b\leq 10^91≤n≤105,1≤a,b≤109


解题思路

又是minminmin又是权值最小,我们可以把问题转换为从xxx走到yyy的权值可以选择axa_xax​或者byb_yby​,然后求最小的权值和。

一个暴力的想法是对于每个axa_xax​对应一个byb_yby​来匹配,但是这样很显然容易导致选出的是若干个小环。

我们可以考虑具体一个点的贡献,我们根据aaa和bbb是否产生了贡献记为一个二进制位,那么每个点的贡献有00,01,10,1100,01,10,1100,01,10,11,考虑什么时候一个方案合法。

把每个a/ba/ba/b视为一个二分图,并且aia_iai​向bib_ibi​连边,然后我们之后连的边中要求两个端点恰好有一个111,确立如下图所示规则:

  1. 11+00=10/01/ring11+00=10/01/ring11+00=10/01/ring
  2. 01+01=01/ring01+01=01/ring01+01=01/ring,同理有10+10=10/ring10+10=10/ring10+10=10/ring
  3. 00+01/10=0000+01/10=0000+01/10=00
  4. 11+01/10=1111+01/10=1111+01/10=11

不难发现一个合法的构造只有两种情况

  1. 全部都是010101或者101010
  2. 000000和111111各有k(k≥1)k(k\geq 1)k(k≥1)个,其余01/1001/1001/10任意

第一种情况直接计算

第二种情况我们对于每一个默认为01/1001/1001/10中权值最小的一个,然后一个01/10→11(ans+max{ai,bi})01/10\rightarrow 11(ans+max\{a_i,b_i\})01/10→11(ans+max{ai​,bi​}),一个01/10→00(ans−min{ai,bi})01/10\rightarrow 00(ans-min\{a_i,b_i\})01/10→00(ans−min{ai​,bi​}),我们可以用两个堆分别维护max{ai,bi}max\{a_i,b_i\}max{ai​,bi​}和min{ai,bi}min\{a_i,b_i\}min{ai​,bi​}

需要注意的是由于第二种情况至少需要一个00/1100/1100/11所以就算第一次会让答案变大也得变,而且有可能出现第一次选择的max{ai,bi}max\{a_i,b_i\}max{ai​,bi​}和min{ai,bi}min\{a_i,b_i\}min{ai​,bi​}是同一个iii,需要特判。

时间复杂度:O(nlog⁡n)O(n\log n)O(nlogn)


code

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define mp(x,y) make_pair(x,y)
#define ll long long
using namespace std;
const ll N=1e5+10;
ll n,a[N],b[N],ans1,ans2,ans;
priority_queue<pair<ll,ll> > q1,q2;
signed main()
{scanf("%lld",&n);for(ll i=1;i<=n;i++){scanf("%lld%lld",&a[i],&b[i]);ans1+=a[i];ans2+=b[i];q1.push(mp(min(a[i],b[i]),i));q2.push(mp(-max(a[i],b[i]),i));ans+=min(a[i],b[i]);}pair<ll,ll> x=q1.top(),y=q2.top();if(x.second==y.second){q1.pop();q2.pop();pair<ll,ll> l=q1.top(),r=q2.top();ans+=min(-r.first-x.first,-y.first-l.first);}else{q1.pop();q2.pop();ans+=-y.first-x.first;while(1){ll x=q1.top().first,y=-q2.top().first;q1.pop();q2.pop();if(x<=y)break;ans+=y-x;}}printf("%lld\n",min(ans,min(ans1,ans2)));return 0;
}

AT4437-[AGC028C]Min Cost Cycle【结论,堆】相关推荐

  1. LeetCode 746. Min Cost Climbing Stairs--动态规划--Java,C++,Python解法

    题目地址:Min Cost Climbing Stairs - LeetCode LeetCode 动态规划(Dynamic programming)系列题目:LeetCode 动态规划(Dynami ...

  2. cf 1511 D. Min Cost String

    cf 1511 D. Min Cost String 题意: 我们规定一个字符串的费用为存在一个i和j(i<j),然后s[i] = =s[j] && s[i+1] = =s[j+ ...

  3. C#LeetCode刷题之#746-使用最小花费爬楼梯( Min Cost Climbing Stairs)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4016 访问. 数组的每个索引做为一个阶梯,第 i个阶梯对应着一个 ...

  4. 746. Min Cost Climbing Stairs 题解

    leetcode.com/problems/min-cost-climbing-stairs/ minCost[n]: 达到台阶n需要消耗的最小成本 Cost[n]: 台阶n自身的成本 递推式为 mi ...

  5. 【动态规划 斐波那切数列】LeetCode 746. Min Cost Climbing Stairs

    LeetCode 746. Min Cost Climbing Stairs 本博客转载自:http://www.cnblogs.com/grandyang/p/8343874.html 存在无代价的 ...

  6. Leetcode 746. Min Cost Climbing Stairs

    思路:动态规划. 1 class Solution { 2 //不能对cost数组进行写操作,因为JAVA中参数是引用 3 public int minCostClimbingStairs(int[] ...

  7. [dp]leetcode 746. Min Cost Climbing Stairs

    输入:一个数组cost,cost[i]表示越过第i个台阶的代价(可能是热量,也可能是过路费) 输出:走过这n个台阶,需要的最小代价 规则:一旦你为第i个台阶付出代价cost[i],那么你可以到达第i+ ...

  8. [AtCoder]Grand Contest 028

    A Two Abbreviations 题意:给定两个串,长度为\(N\)的\(A\)和长度为\(M\)的\(B\),一个串\(S\)被称为好的,当且仅当:这个串的长度\(L\)能被\(N,M\)整除 ...

  9. AtCoder Grand Contest 028题解

    C - Min Cost Cycle 思路好6啊,考试想了半天都没有想出来. 一直在想一个错误的贪心算法. 首先,我们把加一条权值为$min(Ax,By)$的边变成两条权值分别为$Ax,By$的边. ...

最新文章

  1. 高中计算机个人总结怎么写,毕业生自我总结范文
  2. c语言文件发送程序,C语言程序例程的文件结构
  3. echarts树状图点击展开子节点_CPU眼里的结构设备树节点及属性详解
  4. drawroundrect java_Canvas中drawRoundRect()方法介绍
  5. [bzoj3532][Sdoi2014]Lis
  6. 7-2 合并两个有序数组为新的有序数组 (15 分)
  7. win7/win8/win8.1 telnet命令无法使用的解决方案(提示不是内部命令或外部命令)
  8. C#中的三层前馈神经网络,带有图形显示
  9. R in action读书笔记(3)-第六章:基本图形
  10. python web开发-flask中消息闪现flash的应用
  11. nginx发布PHP代码,nginx服务器配置返回php代码
  12. Fread函数的用法
  13. 帆软报表帮助文档_给大家分享一款值得推荐的免费好用的web报表插件
  14. java 电子签章 开源_java操作pdf制作电子签章 - CSDN博客
  15. 色彩专题(PS的颜色理论)
  16. 关于MybatisPlus
  17. python各类地图绘制
  18. 牛顿迭代法求高次方程的根
  19. html图片按钮按钮点击效果
  20. C语言打印杨辉三角的多种方法

热门文章

  1. dockerfile文件名_Linux云计算教程全套视频合集:Dockerfile详解(一)
  2. HTML手机上图片显示被压扁,在重新调整Web浏览器HTML |时,文本会被压扁CSS
  3. 点击ride界面edit空白_『技术锦囊』如何在SOLIDWORKS界面调用宏程序?
  4. java综合图形界面程序设计_java综合图形界面程序设计.doc
  5. java 生成jar_java如何生成jar
  6. 跨部门不配合工作_跨部门协作,队友总是“甩锅”,这三个方法教你快速避坑!...
  7. hadoop安装详细步骤_推荐一个超详细的Hadoop安装教程,已有32万次阅读
  8. suse linux 文件只可读,SUSE LINUX下文件系统变只读的问题解决
  9. [设计模式]模板方法模式
  10. [蓝桥杯][算法提高VIP]夺宝奇兵-dp