测评会员优惠活动进行中 · 开通 VIP,有效期内测评不限次 VIP 优惠中 · 测评不限次 立即查看

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

填空题 困难

题目描述

网络寻路

问题描述

X 国的一个网络使用若干条线路连接若干个节点,节点间的通信是 双向 的。

某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。

该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。

源地址和目标地址可以相同,但中间节点必须不同。

如图所示的网络:

1 -> 2 -> 3 -> 1 是允许的

1 -> 2 -> 1-> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。

输入格式

输入数据的第一行为两个整数 N,M,分别表示节点个数和连接线路的条数。

接下去有 M 行,每行为两个整数 u 和 v,表示节点 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

数据范围

参考答案

#include <iostream> #include <cstring> #include <vector> using namespace std; const int N = 10010, M = 100010; bool st[N]; int n, m, ans; vector<int> h[N]; void dfs(int u, int k, int root) { if(k == 3) // 恰好转发 2 次 { for (int i = 0; i < h[u].size(); i ++) { int j = h[u][i]; if(!st[j] || j == root) ans ++; // 第四个点第一次出现,或者和起点相同 } return; } for (int i = 0; i < h[u].size(); i ++) { int j = h[u][i]; if(st[j]) continue; st[j] = true; dfs(j, k + 1, root); st[j] = false; } } int main() { cin >> n >> m; for (int i = 1; i <= m; i ++) { int a, b; cin >> a >> b; h[a].push_back(b); h[b].push_back(a); } for (int i = 1; i <= n; i ++) { st[i] = true; dfs(i, 1, i); // 枚举每一个点作为起点 st[i] = false; } cout << ans << endl; return 0; }
上一题 下一题