• 图的深度优先遍历


    #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;
     } 
  • 相关阅读:
    2019ICPC上海站
    “浪潮杯”第九届山东省ACM大学生程序设计竞赛重现赛(2018)
    集合问题
    后缀数组
    141. 周期(KMP)
    求和(矩阵快速幂)
    大数(KMP)
    1270: [蓝桥杯2015决赛]完美正方形
    AC自动机
    8.26作业
  • 原文地址:https://www.cnblogs.com/xiaochi/p/10403553.html
Copyright © 2020-2023  润新知