題目描述:
某省調查城鎮交通狀況,得到現有城鎮道路統計表,表中列出了每條道路直接連通的城鎮。省**「暢通工程」的目標是使全省任何兩個城鎮間都可以實現交通(但不一定有直接的道路相連,只要互相間接通過道路可達即可)。問最少還需要建設多少條道路?
輸入:測試輸入包含若干測試用例。每個測試用例的第1行給出兩個正整數,分別是城鎮數目n ( < 1000 )和道路數目m;隨後的m行對應m條道路,每行給出一對正整數,分別是該條道路直接連通的兩個城鎮的編號。為簡單起見,城鎮從1到n編號。
注意:兩個城市之間可以有多條道路相通,也就是說
3 31 2
1 22 1
這種輸入也是合法的
當n為0時,輸入結束,該用例不被處理。
輸出:對每個測試用例,在1行裡輸出最少還需要建設的道路數目。
樣例輸入:
4 21 3
4 33 3
1 21 3
2 35 2
1 23 5
999 0
0樣例輸出:10
2998
解題關鍵:並查集
**:#include
#include
#include
#define size 1001
int fa[size];
int vist[size];
int n, m;
int find(int x)
void merge(int a, int b)
int main()
while (m--)
for (i = 1; i <= n; ++i)
vist[find(i)] = 1;
for (i = 1, j = 0; i <= n; ++i)
if (vist[i]) j++;
printf("%d\n", j - 1);}}
理解乙個演算法最簡單的方式,就是找乙個例子作為程式輸入進行除錯,跟蹤**的執行過程。
我們以輸入
4 21 3
3 4為例來學習,fa和visit兩個陣列初始化後
fa:1,2,3,4
vist:0,0,0,0
首先merge(1,3),fa:3,2,3,4
再merge(3,4),fa:3,2,4,4,
最後進行visit陣列的賦值,進入迴圈:
vist(find(1)):1!=fa(1),返回find(fa(1))=find(3),返回find(4),最後返回4。
vist(find(2)):返回2
vist(find(3)):返回4
vist(find(4)):返回4
結果vist:0,1,0,1
表明整個圖有兩個連通域,兩個連通域需要一條路連通
最後需要修的道路數就是visit陣列中1的個數-1
總結:並查集的演算法如果用陣列實現用到遞迴,基本思想就是將連通的點,放到同乙個集合。
華為機試題目
在網上找了一些華為機試的題目,每日堅持寫 1 字元 字串與數值間的轉換 分析 int i ch 48 這個語句完成了單個字元 ch 轉化為數字並存入整型變數 i 的功能。因為字元 0 在 ascii 碼中對應了 48,後面的數值也是以 1 遞增,所以用它對應的ascii碼減去48就是這單個字元的整數...
機試題目2011 2019
機試題目彙總 數學 簡單模擬 卡特蘭數2019.3 難 直接上公式 相隔天數2019.1 簡單 日期處理 求眾數2018.1 簡單 用map儲存直接排序或陣列儲存後再排序 求中位數2017.1 簡單 分奇偶 求校驗位2017.2 簡單 看懂題按要求 長方形中的正方形個數2015.1 簡單 邊界條件 ...
華為機試題目整理
最近又到了招聘季了,現在也輪到我畢業了。針對華為的機試題目,我整理了一下自己寫的一部分 參考別人和自己的理解寫的,經過測試,可以執行。一 3.通過鍵盤輸入一串小寫字母 a z 組成的字串。請編寫乙個字串過濾程式,若字串中出現多個相同的字元,將非首次出現的字元過濾掉。比如字串 abacacde 過濾結...