time limit: 30 sec memory limit: 512 mb
submit: 2344 solved: 975
[submit][status][discuss]
給你乙個無向帶權連通圖,每條邊是黑色或白色。讓你求一棵最小權的恰好有need條白色邊的生成樹。
題目保證有解。
第一行v,e,need分別表示點數,邊數和需要的白色邊數。
接下來e行,每行s,t,c,col表示這邊的端點(點從0開始標號),邊權,顏色(0白色1黑色)。
一行表示所求生成樹的邊權和。
v<=50000,e<=100000,所有資料邊權為[1,100]中的正整數。
2 2 1
0 1 1 1
0 1 2 0
原資料出錯,現已更新 by liutian,但未重測—2016.6.24
題解:
考試的前一天看了這道題,然而當時覺得太難了就沒有做,然後考到了:)
首先如果每條白邊的權值逐漸增大的話,那麼最小生成樹上白邊的數量肯定是單調不下降的。所以我們可以利用這個性質來二分乙個權值mid,然後將每條白邊都加上這個mid,再跑最小生成樹。如果最小生成樹上選取的白邊的數量》=need,那麼白邊的權值應該再大一點,反之。
最後就得到了乙個mid,使得所有白邊+mid之後,可以選取到》=need條白邊,但對於mid+1,就小於了need條白邊。這樣肯定可以證明有一些黑邊與白邊的權值一樣,因為資料保證有解,所以即使是大於的,也沒關係,可以選權值一樣的黑邊。
最後的答案就是我們得到這顆生成樹的權值和-mid*need(白邊增量)。
感性理解一下還是很正確的…
#include
#include
#include
using
namespace
std;
inline
int read()
while(ch>='0'&&ch<='9')
return x*f;
}const
int n = 100000 + 10;
const
int inf = 0x7f;
int n,m,need;
struct nodee[n];
bool
operator
< (node a,node b)
int aans=0;
bool check(int mid)
sort(e+1,e+m+1);int cnt=0,ans=0;
for(int i=1;i<=m;++i)
if(ans>=need) return
true;
return
false;
}int main()
for(int i=1;i<=n;++i) fa[i]=i;
sort(e+1,e+m+1);
int cnt=0;
for(int i=1;i<=m;++i)
int l=-100,r=100,ans;
while(l<=r)
printf("%d\n",ans);
return
0;}
BZOJ 2654 tree 二分 最小生成樹
給出一些邊,每個邊有乙個邊權和顏色。現在要求出最小邊權有need個白邊的生成樹。輸出這個邊權。在白邊上加乙個權值,這樣就可以人為的改變白邊出現在最小生成樹。這個東西顯然可以二分。之後取一下最小值就可以了。define crt secure no warnings include include in...
bzoj2654 tree 二分 最小生成樹
time limit 30 sec memory limit 512 mb submit status discuss 給你乙個無向帶權連通圖,每條邊是黑色或白色。讓你求一棵最小權的恰好有need條白色邊的生成樹。題目保證有解。第一行v,e,need分別表示點數,邊數和需要的白色邊數。接下來e行,每...
bzoj2654 tree(二分 最小生成樹)
我是超連結 一開始博主想要把黑白邊分開,然後sort,選擇前need小的白邊連起來,然後再連黑邊 但這個貪心是不對的,因為黑邊的大小不確定,如果目前選擇了較小的白邊,可能會選上更大的黑邊 問題的關鍵在於求出的最小生成樹不一定含有need條白邊 1 如果白邊 need條,我們需要 拖累 白邊,讓ta不...