图的深度优先遍历

#include <iostream>
#include <vector>
using namespace std;

const int MAXV = 1000;
const int INF = 1000000000; 

//图的邻接表 
vector<int> Adj[MAXV];
//顶点数 
int n;
//如果顶点i已经被访问,则vis[i]=true,初始值为false 
bool vis[MAXV] = {false};

//u:当前访问的顶点编号
//depth为深度 
void DFS(int u,int depth)
{
    //输出,并设置顶点已经被访问 
    cout << u ;
    vis[u] = true;
    
    
    for(int i=0;i<Adj[u].size();i++)
    {
        //与u相接的顶点 
        int v = Adj[u][i];
        //如果没有被访问 
        if(vis[v] == false)
        {
            DFS(v,depth + 1);
        }
    }
 } 
 
 
 int main()
 {
    
    Adj[0].push_back(1);
     Adj[0].push_back(2);
     Adj[1].push_back(0);
     Adj[1].push_back(2);
     Adj[1].push_back(3);
     Adj[1].push_back(4);
     Adj[2].push_back(0);
    Adj[2].push_back(1);
    Adj[2].push_back(4);
    Adj[3].push_back(1);
    Adj[3].push_back(4);
    Adj[3].push_back(5);
    Adj[4].push_back(1);
    Adj[4].push_back(2);
    Adj[4].push_back(3);
    Adj[4].push_back(5);
    Adj[5].push_back(1);
    Adj[5].push_back(4);

    DFS(0,1);
     return 0;
 }

 题目练习:PAT A1034 Head of a Gang

 

#include <iostream>
#include <vector>
#include <string>
#include <map>
#include <algorithm>
using namespace std;

const int maxn = 2100;
const int INF = 1000000000; 

map<int,string> intToString;//编号到姓名的映射
map<string,int> stringToInt;//姓名到编号
map<string,int> Gang;//头目到团体人数

int G[maxn][maxn] = {0};//邻接矩阵
int weight[maxn] = {0};//点权

int numPerson = 0;
bool vis[maxn] = {false};

int n,k;//n为边数,k为阈值

//从string转成id 
int change(string str)
{
    //判断是否出现过 
    if(stringToInt.find(str) != stringToInt.end())
    {
        return stringToInt[str];
    }    
    else
    {
        stringToInt[str] = numPerson;
        intToString[numPerson] = str;
        return numPerson++;//总人数加1 
    }
}

void DFS(int nowVisit,int &head,int &numMember,int &totalValue)
{
    //团体成员数量+1 
    numMember++;
    //标记为已经访问 
    vis[nowVisit] = true;
    
    
    if(weight[nowVisit] > weight[head])
    {
        //如果当前访问节点的点权大于头目的点权,则更新头目 
        head = nowVisit;
    }
    
    //从该点开始遍历相邻的所有节点 
    for(int i=0;i < numPerson;i++)
    {
        //从nowVisit能到达i 
        //访问完的边不再访问,即删掉,以防回头(此种情况适合每条边只遍历一次) 
        if(G[nowVisit][i] > 0) 
        {
            totalValue += G[nowVisit][i]; 
            G[nowVisit][i] = G[i][nowVisit] = 0;
            //如果i没有被访问,则递归访问i 
            if(vis[i] == false)
            {
                DFS(i,head,numMember,totalValue);    
            } 
        } 
    } 
}

void DFSTrave()
{
    for(int i=0;i<numPerson;i++)
    {
        //如果i没有被访问,假设i为头子 
        if(vis[i] == false)
        {
            int head = i;
            int numMember = 0;//成员数量为0
            int totalValue = 0;//总的边权
            
            //遍历连通块
            DFS(i,head,numMember,totalValue); 
            
            //总人数大于2,且边大于k 
            if(numMember > 2 && totalValue > k)
            {
                Gang[ intToString[head] ] = numMember;
            } 
        }
    }
}

int main()
{
    int w;//权值
    string str1,str2;
    
    
    
    cin >> n >> k;
    
    while(n--)
    {
        cin >> str1 >> str2 >> w; //输入边的两个端点和点权 
        int id1 = change(str1);//将str1转换成编号id1
        int id2 = change(str2);//将str2转换为编号id2
        weight[id1] += w;
        weight[id2] += w;
        G[id1][id2] += w;
        G[id2][id1] += w; 
    } 
    
    DFSTrave(); 
    cout << Gang.size() << endl;
    
    //输出信息 
    for(map<string,int>::iterator it = Gang.begin();it != Gang.end();it++)
    {
        cout << it->first << " " << it->second << endl;
    }
    
    return 0;
 } 

 

posted @ 2019-02-19 21:46  喵小喵~  阅读(189)  评论(0编辑  收藏  举报