題目20 吝嗇的國度

2021-08-07 21:51:10 字數 1597 閱讀 4262

在乙個吝嗇的國度裡有n個城市,這n個城市間只有n-1條路把這個n個城市連線起來。現在,tom在第s號城市,他有張該國地圖,他想知道如果自己要去參觀第t號城市,必須經過的前乙個城市是幾號城市(假設你不走重複的路)。

第一行輸入乙個整數m表示測試資料共有m(1<=m<=5)組

每組測試資料的第一行輸入乙個正整數n(1<=n<=100000)和乙個正整數s(1<=s<=100000),n表示城市的總個數,s表示參觀者所在城市的編號

隨後的n-1行,每行有兩個正整數a,b(1<=a,b<=n),表示第a號城市和第b號城市之間有一條路連通。

每組測試資料輸n個正整數,其中,第i個數表示從s走到i號城市,必須要經過的上乙個城市的編號。(其中i=s時,請輸出-1)

1 10 1

1 9

1 8

8 10

10 3

8 6

1 2

10 4

9 5

3 7-1 1 10 10 9 8 3 1 1 8

這是一道典型的深度搜尋的題目,這些城市與道路構成了乙個極小連通子圖,也就是生成樹。由於節點數太大,不能使用二維陣列儲存,可以考慮使用vectora[100005]來儲存,這樣可以減少部分儲存空間,但仍然是指標不治本。看了網上的一段**,覺得可以借鑑,所以來過來記錄一下。

首先,給定的是乙個無向圖,我們需要做的是將這個無向圖構造儲存為乙個以開始城市節點為根節點的一棵樹(有向圖)。這樣就可以知道每個城市的父節點,然後迴圈輸出即可。

構造這顆樹的方法:首先,使用mp[i]來記錄從s節點到i節點必須經過的上乙個城市節點的編號。

比如:mp[b] = a,也就是在有向圖中a指向b,即要達到b城市必須經過的上乙個城市是a。

初始化mp[i]=0;

則對於每組邊的兩節點a,b

若mp[b]=0,即無城市指向b,則令a指向b:mp[b]=a

若mp[b]!=0, 即表明已經有其他城市指向b,那麼,這時當然要將b指向a城市,即mp[a]=b;

但是在將b指向a之前,需要考慮是已經有其他城市已經指向了a,如果已經有的話,冒然賦值則會覆蓋以前的值。

所以,在此之前,我們需要將所有指向a的城市節點,方向調換,即若t指向a,則改為a指向t

同時,再以t為起始遞迴下去,這樣就可以讓已a為起點的一系列有向線路全部轉換方向,實現180轉彎。

經過上述操作我們已經得到乙個有向圖,但仍然不能滿足題目要求,因為起點是s,故每個有向線路的起點必然是由s開始的,

所以,我們對s點,進行上述的遞迴操作,此時,任務完成,所有的有向路都是已s點為出發點的了。

#include

#include

#include

#include

int m, n, s, mp[100005];

void def(int s)

}int main(void)

else

}def(s);

mp[s] = -1;

for (int i = 1; i <= n; i++)

printf("\n");

}return

0;}

題目20 吝嗇的國度

吝嗇的國度 時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述在乙個吝嗇的國度裡有n個城市,這n個城市間只有n 1條路把這個n個城市連線起來。現在,tom在第s號城市,他有張該國地圖,他想知道如果自己要去參觀第t號城市,必須經過的前乙個城市是幾號城市 假設你不走重複的路 輸入第一...

NYOJ 題目20 吝嗇的國度

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 在乙個吝嗇的國度裡有n個城市,這n個城市間只有n 1條路把這個n個城市連線起來。現在,tom在第s號城市,他有張該國地圖,他想知道如果自己要去參觀第t號城市,必須經過的前乙個城市是幾號城市 假設你不走重複的路 輸入第一行輸入乙個...

nyoj20 吝嗇的國度

時間限制 1000 ms 記憶體限制 65535 kb 難度 3 描述 在乙個吝嗇的國度裡有n個城市,這n個城市間只有n 1條路把這個n個城市連線起來。現在,tom在第s號城市,他有張該國地圖,他想知道如果自己要去參觀第t號城市,必須經過的前乙個城市是幾號城市 假設你不走重複的路 輸入第一行輸入乙個...