时间限制: 1Sec 内存限制: 128MB 提交: 21 解决: 9
题目描述
X 国的一个网络使用若干条线路连接若干个节点。节点间的通信是双向的。某重要数据包,为了安全起见,必须恰好被转发两次到达目的地。该包可能在任意一个节点产生,我们需要知道该网络中一共有多少种不同的转发路径。
源地址和目标地址可以相同,但中间节点必须不同。
如下图所示的网络。
1 -> 2 -> 3 -> 1 是允许的
1 -> 2 -> 1 -> 2 或者 1 -> 2 -> 3 -> 2 都是非法的。
源地址和目标地址可以相同,但中间节点必须不同。
如下图所示的网络。
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)。
输入数据保证任意两点最多只有一条边连接,并且没有自己连自己的边,即不存在重边和自环。
接下去有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-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; }