AT4437-[AGC028C]Min Cost Cycle【结论,堆】
正題
題目鏈接: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,確立如下圖所示規則:
不難發現一個合法的構造只有兩種情況
第一種情況直接計算
第二種情況我們對于每一個默認為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【结论,堆】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 音乐剪辑怎么弄电脑如何剪辑音乐软件
- 下一篇: P7011-[CERC2013]Esca