UVA 1151二進位制列舉子集 最小生成樹

2022-04-05 15:36:06 字數 1605 閱讀 7451

題意:平面上有n個點(1<=n<=1000),你的任務是讓所有n個點連通,為此, 你可以新建一些邊,費用等於兩個端點的歐幾里得距離的平方。另外還有q(0<=q<=8)個**(數量小,可列舉),可以購買,如果你購買了第i個**,該** 中的所有結點將變得相互連通,第i個**的花費為ci。

分析:按照劉汝佳的思路做的。首先求一次本身的最小生成樹值,然後列舉購買的**(二進位制列舉),每次購買了之後,將其權值設為0,並且加進最小生成樹。

1 #include2 #include3 #include4

#define ll long long

5using

namespace

std;

6const

int maxn=1005;7

intx[maxn],y[maxn],p[maxn];

8#define repu(i, a, b) for(int i = (a); i < (b); i++)

9int bb[260

];10

int tran(int

h)11

19return

i;20}21

int find(int

x)22

25struct

edge

2633 } _e[maxn*maxn],e[maxn];

34int q[8][maxn],c[8],t[8

];35

intn,m,r,cnt;

36void

init()

3740

ll kruscal()

4151}52

return

ret;53}

54int

main()

5568 repu(i,1,n+1

)69 scanf("

%d%d

",&x[i],&y[i]),p[i]=i;

70 repu(i,1

,n)71 repu(j,i+1,n+1

)72 _e[++m]=(edge)73;

76 sort(_e+1,_e+m+1

);77 ll ans=0

;78 repu(i,1,m+1)79

89 }///

本身的最小生成樹

90 repu(b,0,1

<

91106

}107

}108 ansx +=kruscal();

109 ans=min(ans,ansx);

110}

111 printf("

%lld\n

",ans);

112if(t) printf("\n"

);113

}114

return0;

115 }

view code

每次求最小生成樹的時候,都會加進去幾條權值是0的邊,一定會被選,剩下的邊也一定會從裸求的最小生成樹種找到。第一求的時候捨棄的邊可以永遠捨棄。

二進位制列舉子集

利用二進位制的 開關 特性列舉 詳細為 如果給定集合a大小為n,則想象a 的每乙個元素相應乙個開關位 0或1 0表示不出現,1表示出現。當每乙個元素的開關位的值確定時,就得到乙個子集。因此共同擁有2 n 1種情況 全0為空集,這裡不考慮 我們利用區間 1,2 n 1 該區間上的每乙個整數相應乙個子集...

技巧 二進位制法列舉子集

我們來看乙個可以用二進位制列舉的方法解決的題目 話說大詩人李白,一生好飲 幸好他從不開車 一天,他提著酒壺,從家裡出來,酒壺中有酒兩斗 他邊走邊唱 無事街上走,提壺去打酒 逢店加一倍,遇花喝一斗 這一路上,他一共遇到店 5 次,遇到花 10 次,已知最後一次遇到的是花,他正好把酒喝光了 請你計算李白...

做實驗 解題報告(二進位制列舉子集)

有一天,你實驗室的老闆給你布置的這樣乙個實驗。首先他拿出了兩個長度為 n 的數列 a 和 b,其中每個 a i 以二進位制表示乙個集 合。例如數字 5 101 2 表示集合 第 i 次實驗會準備乙個小盒子,裡面裝 著集合 a i 所有非空子集的紙條。老闆要求你從中摸出一張紙條,如果滿足你摸出的 紙條...