您的位置:首页 > 理论基础 > 计算机网络

历届试题网络寻路(dfs)

2017-05-18 21:04 225 查看
问题描述

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)。

输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。

输出格式

输出一个整数,表示满足要求的路径条数。

样例输入1

3 3

1 2

2 3

1 3

样例输出1

6

样例输入2

4 4

1 2

2 3

3 1

1 4

样例输出2

10

 题意 从一个点出发到一个点,在转发两次 1->2 再由2->3 3->1进行转发,不相等的意思就是除了起点和终点可以相同之外,其他都不能相同

开始的时候我的思路是每次暴力搜4段,判断不相等则可以算一次,思路是正确的,但是n较大的时候,一个点和它没有关系的点进行多次判断,

循环次数一多,肯定是不行的;

看看百度,各位博友用了vector,我也来一发,用vector来保存与某个点有关的点,每次循环都是在与其相连的点进行运算,比用仅仅用

一个二维数组来保存任意两个点的关系是否是连接的要快的多

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<string.h>
#include<vector>
using namespace std;
struct st
{
vector<int> arr;
}map[10001];
int n,m,b[5],cnt=0;

void dfs(int x, int num)//x为找到 的路数 ,num是出发点,也是下次要走的点
{
int i,j,k;
if (x > 4 )
{
if (b[2]!=b[3] && b[2]!=b[1] &&b[2]!=b[4] && b[3]!=b[1] && b[3]!=b[4])
cnt++;
return ;
}
for (i=0; i<map[num].arr.size(); i++)//缩减不必要的循环
{
b[x] = map[num].arr[i];
dfs(x+1,map[num].arr[i]);
}
}
int main()
{
int x,y,i,j,k;
cin>>n>>m;
for (i=1; i<=m; i++)
{
scanf("%d%d",&x,&y);
map[x].arr.push_back(y);
map[y].arr.push_back(x);
}
for (i=1; i<=n; i++)
{
b[1] = i;
dfs(2,i);//寻找 从i出发的路
}
cout<<cnt;
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: