DFS遍歷圖時的小技巧

DFS遍歷圖時的小技巧

咱們一般使用DFS遍歷圖時,用vis[i]=true;來標記訪問過的節點,可是若是要讓咱們統計圖中全部邊的長度的話,若是咱們還這樣作的話,對於非環形圖來講,沒問題,可是對於環形圖來講,就可能訪問不到最後一條邊,如A-B-C-A,A標記以後就不能統計到C-A了。
這時咱們的辦法是,每訪問一條邊後,就把它銷燬,而後遞歸地去DFS時再也不以vis[i]==false爲條件去遞歸,而是直接以G[i][j]!=0爲條件去遞歸。
這也是和平時DFS遍歷圖時有區別的地方,一個小技巧吧。ios

後來又看到別人的解法,先訪問邊,再判斷vis[i],再去DFS,可見下面的DFS法二。c++

應用:1034 Head of a Gang (30 分)spa

//此題的難點在於DFS遍歷每個點後,都銷燬走過的路徑,不走回頭路。 
//在遞歸時,再也不以vis[i]==false問判斷條件 ,由於vis[i]=true標記後,若是是環形圖的話,那麼最後一條邊就不能訪問到
//如A-B-C-A,剛開始時A被標記後,那麼C-A這條邊就不能在被訪問到。 
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
using namespace std;

const int maxn=2010;//不能定義爲1010時,會有段錯誤,必須定義爲2000以上,因爲通話記錄有1000條,所以不一樣的人可能有2000個 
struct Gang{
    int head;
    int num;
};
int G[maxn][maxn];
int W[maxn];
bool vis[maxn];
int n,K;
vector<Gang> ans;
map<string,int> stringToInt;
map<int,string> intToString;
int numPerson;
int maxConnTime;
void DFS(int idx,int &total,int &num,int &head){
    if(vis[idx]==false){
        num++;
        vis[idx]=true;
    }
    if(W[idx]>maxConnTime){
        maxConnTime=W[idx];
        head=idx;           
    }
    for(int i=0;i<numPerson;i++){
        if(G[idx][i]){//這裏不在以vis[i]==false爲條件,由於對於環形圖訪問不到最後一條邊 
            total+=G[idx][i];
//          num++;
            G[idx][i]=G[i][idx]=0;//訪問後銷燬邊 
            DFS(i,total,num,head);
        }
    }
}
//法二 :先訪問邊,再DFS遍歷 
/** 
void DFS(int idx,int &total,int &num,int &head){
    num++;
    vis[idx]=true;
    if(W[idx]>maxConnTime){
        maxConnTime=W[idx];
        head=idx;           
    }
    for(int i=0;i<numPerson;i++){
        if(G[idx][i]){
            total+=G[idx][i];
            G[idx][i]=G[i][idx]=0;
            if(vis[i]==false){
                DFS(i,total,num,head);  
            } 
        }
    }
}
*/ 
bool cmp(Gang a,Gang b){
    return intToString[a.head]<intToString[b.head];
}
int transfer(string name){
    if(stringToInt.find(name)==stringToInt.end()){
        stringToInt[name]=numPerson;
        intToString[numPerson]=name;
        return numPerson++;
    }else{
        return stringToInt[name];
    }
}
int main(){
    cin>>n>>K;
    for(int i=0;i<n;i++){
        string a,b;
        int w;
        cin>>a>>b>>w;
        int aId=transfer(a);
        int bId=transfer(b);
        G[aId][bId]+=w;
        G[bId][aId]=G[aId][bId];
        W[aId]+=w;
        W[bId]+=w;
    }
    for(int i=0;i<numPerson;i++){
        if(vis[i]==false){
            int total=0,num=0,head;
            maxConnTime=0;
            DFS(i,total,num,head);
            if(total>K&&num>2){
                Gang gang;
                gang.head=head,gang.num=num;
                ans.push_back(gang);
            }    
        }
    }
    sort(ans.begin(),ans.end(),cmp);
    cout<<ans.size()<<endl;
    for(int i=0;i<ans.size();i++){
        cout<<intToString[ans[i].head]<<" "<<ans[i].num<<endl;
    }
    
    return 0;
}
相關文章
相關標籤/搜索