天天看點

nyoj20(dfs)

吝啬的國度

時間限制:1000 ms  |  記憶體限制:65535 KB 難度:3

描述
在一個吝啬的國度裡有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      

題意:

找到去某個城市的上一個城市,現在你在的城市設為-1,輸出n個數字,表示要去的城市前的城市;

解題思路:

将該點的所有關聯點放在一起,通過深搜找到該點的每個前驅,判斷該前驅點是否通路,如果沒有通路繼續下一個點,直到找到滿足的點繼續深搜!

将值存入vector容器數組中,然後通過深度周遊,遞歸的周遊所有的點,設立的标志數組,如果通路過了就将其值指派為1(原來是0)

nyoj20(dfs)

代碼如下;

<span style="font-size:18px;">#include <iostream>  
#include <memory.h>  
#include <stdio.h>  
#include <queue>  
#include <vector>  
using namespace std;  
  
vector<int> ls[100002];  
int pre[100002];  
char flag[100002];  
int n, sx;  
void dfs(int v)  
{  
    flag[v] = 1;  
    vector<int>::iterator it, itEnd;  
    it = ls[v].begin();  
    itEnd = ls[v].end();  
    int cur;  
    for (; it != itEnd; ++it)   //依次通路相鄰的頂點  
    {  
        cur = *it;  
        if (!flag[cur])         // 未被通路  
        {  
            pre[cur] = v;       // 儲存前一個城市  
            dfs(cur);           // 繼續通路下一個  
        }  
    }  
} 
int main()  
{  
    int x, y, m;  
    cin>>m;  
    while (m--)  
    {  
        memset(flag, 0, sizeof(flag));  
        cin>>n>>sx;  
        for ( int i=1; i<=n; ++i)  
            ls[i].clear();  
        for (int j=1; j<n; ++j)  
        {  
            cin>>x>>y;  
            ls[x].push_back(y);  
            ls[y].push_back(x);  
        }  
        dfs(sx);    // 從所在位置搜尋    
        pre[sx] = -1;  
        cout<<pre[1];  
        for (int k=2; k<=n; ++k)  
        {  
            cout<<" "<<pre[k];  
        }  
        cout<<endl;  
    }  
    return 0;  
}   </span>