考慮乙個小貪心。
將 \(2\) 小時和 \(5\) 小時的節點放在一起按分數從小到大排序,如果分數相同則將 \(2\) 小時的節點放在前面。
然後對於每個\(5\) 小時節點,我們找到未匹配的且分數最大的且國籍相同的 \(2\) 小時節點並且將它與該節點匹配。
但是我們會發現乙個問題。這麼做了之後剩下的點可能不能夠互相匹配。
否則,那麼答案就是剩下的點數\(/\;2\) 。
我們考慮魔改貪心過程,使得讓貪心過程中保證剩下的點能夠互相匹配。
這樣答案就是剩下的點數\(/\;2\) 了。
我們注意到這個問題可以抽象成二分圖最大匹配的模型。
所以我們可以考慮 hall 定理
對於乙個二部圖 \(g(x,y)\),\(x\) 存在乙個匹配的充分必要條件為對於 \(x\) 的任意子集 \(s\),\(s\) 的鄰居個數 \(n(s)\) 必須大於等於 \(s\) 的大小 \(|s|\)。注意到原圖有點特殊,對於乙個點 \(x\) 來說,所有排序後在他之前,且不是跟他乙個型別(就是不是都是 \(2\) 小時或 \(5\) 小時的點)的點都跟他有邊。也就是乙個點的所連的點集是它的字首。
所以對於 \(x\) 任意乙個子集 \(s\) 來說,\(n(s)\) 就等於 \(s\) 中分最大的那個點的邊集。
所以所有的 \(n(s)>0\) 相當於是對於排序後的每個點 \(i\) 。在 \(i\) 之前存在的 \(x\) 部的點的數量與 \(y\) 部的點的數量要相同。
我們可以用線段樹來維護(相當於是 \(x\) 部的點權為負,\(y\) 部點權為正,詢問字首最小值是否小於 \(0\) ,讓線段樹支援區間查詢最值和區間修改即可)。
每次加入乙個 \(5\) 小時的點,判斷和它同國籍且分數最大的點跟他匹配後還存不存在完全匹配。
正確性顯然。
時間複雜度為 \(o(n\log n)\)。
**如下:
#includeusing namespace std;
const int maxn = 4e5+5;
struct tree
void pu(int k)
void pd(int k)
void upd(int le,int ri,int k,int l,int r,int x)
int mid=l+r>>1;pd(k);
if(le<=mid) upd(le,ri,ls(k),l,mid,x);
if(ri>mid) upd(le,ri,rs(k),mid+1,r,x);
pu(k);
} int que(int le,int ri,int k,int l,int r)
}t;struct node; }
for(int i=1;i<=n;++i)
; }n*=2;
sort(a+1,a+1+n);
int ans=n/2;
for(int i=1;i<=n;++i)
else
int p=st[a[i].p].top();
t.upd(p,n,1,1,n,-1);
if(t.que(1,i,1,1,n)<0)
else ans--,st[a[i].p].pop();
} }printf("%d\n",ans);
return 0;
}
題解 JOISC 2016 Day 3 電報
題目傳送門 給出乙個 n 個點 n 條邊的圖,每個點有且僅有乙個出邊,改變每條邊都會有對應的花費。求最小的花費使得整個圖強連通。很顯然,最後的圖就是乙個環。那我們要求的答案實際上就是鏈的最大權值之和。我們再次將問題轉換,發現就是每個點只保留一條邊,而保留的邊就是連向它的邊權最大的邊。但是我們發現這實...
JOISC 2016 Day 3 迴轉壽司
joisc 2016 day 3 迴轉壽司 這題我無力吐槽了.強烈譴責出題人用腳造資料 其實這題主要還是部分分啟發正解吧。看到有個 s i 1,t i n 的做法就是維護乙個堆就可以了,所以擴充套件下就是分塊,然後每個塊維護乙個堆。散塊暴力,大塊直接查。但是有個很坑爹的問題在於,對於整塊的部分我們沒...
JOISC 2020 Day1 建築裝飾 4
loj 考慮設 f 表示到了第 i 個位置,用了 j 個a,k 個b的可行性,打表發現對於 i,j 的 k 是連續的,所以考慮記錄 l 表示前 i 個位置用了 j 個a最少用多少個b,r 同理.最後輸出方案的時候一步一步的倒推即可.include include include include in...