• [蓝桥杯][历届试题]网络寻路


    时间限制: 1Sec 内存限制: 128MB 提交: 21 解决: 9

    题目描述
    X  国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。 
    源地址和目标地址可以相同,但中间节点必须不同。 
    如下图所示的网络。 

    1  ->   2  ->   3  ->   1  是允许的 
    1  ->   2  ->   1  ->   2  或者  1  ->   2  ->   3  ->   2  都是非法的。 
    输入
    输入数据的第一行为两个整数N  M,分别表示节点个数和连接线路的条数(1< =N< =10000;  0< =M< =100000)。 
    接下去有M行,每行为两个整数  u  和  v,表示节点u  和  v  联通(1< =u,v< =N  ,  u!=v)。 
    输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。 
    输出
    输出一个整数,表示满足要求的路径条数。
    样例输入
    4  4 
    1  2 
    2  3 
    3  1 
    1  4  
    样例输出
    10

    分析题目要求:

    1. 首相明确有两种目的地,一种是回到原点,一种是到达一个没有到过的地方;

    2. 路径中经过的点不能够有重复的点;

    3. 根据题目给出的数据可以发现,1-2-3-4  和 4-3-2-1是两条不同的路径。

    解体思路:

     1.使用vis[]数组记录经过的点;

     2.使用DFS寻找可能的路径,因为路径的长度是4,那么当寻找路径上的前3个点的时候,如果可以从前一个点走到当前的点,并且当前的点没有走过,那么将当前的点设置为路径当中的点。

     3.寻找路径第四个点的时候,有两种可能的情况,一种是可以到达的第四个点是之前没有走过的点,方案数量加一,另外一的情况是可以到达的第四个点是第一个点(走回到了起点),方案数量加一。

        
    注意事项:
     1.使用vector创建一个邻接表,如果使用邻接矩阵,容易时间超限。

    #include<cstdio>
    #include<iostream>
    #include<algorithm>
    #include<vector>
    #define maxn 100100
    using namespace std; 
    int n,m,vis[maxn/10],ans;
    typedef struct Road{
        int start,end;
    }Road;
    vector<int> box[maxn/10];
    void dfs(int f,int pre,int cur)
    {
        if(cur<=2)
        {
            for(int i=0;i<box[pre].size();i++)
            {
                int next=box[pre][i];
                if(!vis[next])
                {
                    vis[next]=1;
                    dfs(f,next,cur+1);
                    vis[next]=0;
                } 
            }
        }
        if(cur==3)
        {
            for(int i=0;i<box[pre].size();i++)
            {
                int next=box[pre][i];
                if(!vis[next]) ans++;
                if(next==f)    ans++;
            }    
        } 
    }
    int main(void)
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
        {
            int start,end;
            scanf("%d%d",&start,&end);
            box[start].push_back(end);
            box[end].push_back(start);
        }
        for(int i=1;i<=n;i++)
        {
            vis[i]=1;
            dfs(i,i,1);
            vis[i]=0;    
        }    
        printf("%d",ans);
        return 0;
    } 
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 数的统计
    Java实现 蓝桥杯VIP 算法训练 和为T
    Java实现 蓝桥杯VIP 算法训练 友好数
    Java实现 蓝桥杯VIP 算法训练 连续正整数的和
    Java实现 蓝桥杯VIP 算法训练 寂寞的数
    Java实现 蓝桥杯VIP 算法训练 学做菜
    Java实现 蓝桥杯VIP 算法训练 暗恋
    Java实现 蓝桥杯VIP 算法训练 暗恋
    测试鼠标是否在窗口内,以及测试鼠标是否在窗口停留
    RichEdit 各个版本介绍
  • 原文地址:https://www.cnblogs.com/zuimeiyujianni/p/8735068.html
Copyright © 2020-2023  润新知