问题描述
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
思路:暴力dfs加剪枝。依次从每个节点出发,找到一个长度为四的路径,可以为环,保证第一个节点不可以和第二个第三个节点相同,第四个节点不可以和第三个节点的和第二个节点相同
代码1如下:
1 #include<bits/stdc++.h>
2 using namespace std;
3 int Amap[5001][5001];
4 int array[4];
5 int start;
6 int end;
7 int sum=0;
8 int t=1;
9 int N,M;
10 void dfs(int n)
11 {
12 if(t==3){
13 for(int i=1;i<=N;i++){
14 if(Amap[n][i]==1){
15 sum++;
16 }
17 }
18 sum--;
19 }else{
20 for(int i=1;i<=N;i++){
21 if(Amap[n][i]==1){
22 array[t]=i;
23 if(t==1){
24 t++;
25 dfs(i);
26 t--;
27 }
28 if(t==2){
29 t++;
30 if(array[0]!=array[2]){
31 dfs(i);
32 }
33 t--;
34 }
35
36 }
37 }
38 }
39 }
40 int main()
41 {
42 memset(Amap,0,sizeof(Amap));
43 memset(array,0,sizeof(array));
44
45 cin >> N>> M;
46 for(int i=0;i<M;i++){
47 cin >> start >> end;
48 Amap[start][end]=Amap[end][start]=1;
49 }
50 for(int i=1;i<=N;i++){
51 array[0]=i;
52 dfs(i);
53 }
54 cout << sum;
55 return 0;
56 }
由于第五组测试数据过大,数组不可以分那么多的空间,考虑使用vector代码如下:
代码2:
1 #include<bits/stdc++.h>
2 using namespace std;
3 vector<int> Amap[10010];
4 int array[4];
5 int start;
6 int end;
7 int sum=0;
8 int t=1;
9 int N,M;
10 void dfs(int n)
11 {
12 if(t==3){
13 for(vector<int>::iterator iter=Amap[n].begin();iter<Amap[n].end();iter++){
14 sum++;
15 }
16 sum--;
17 }else{
18 for(vector<int>::iterator iter=Amap[n].begin();iter<Amap[n].end();iter++){
19 array[t]=*iter;
20 if(t==1){
21 t++;
22 dfs(*iter);
23 t--;
24 }
25 if(t==2){
26 t++;
27 if(array[0]!=array[2]){
28 dfs(*iter);
29 }
30 t--;
31 }
32
33 }
34 }
35 }
36 int main()
37 {
38 memset(Amap,0,sizeof(Amap));
39 memset(array,0,sizeof(array));
40
41 cin >> N>> M;
42 for(int i=0;i<M;i++){
43 cin >> start >> end;
44 Amap[start].push_back(end);
45 Amap[end].push_back(start);
46 }
47 for(int i=1;i<=N;i++){
48 array[0]=i;
49 dfs(i);
50 }
51 cout << sum;
52 return 0;
53 }
总结:当我们发现自己掌握的知识已经解决不了当前的问题时,我们一定要去学习,而学习到新的东西并且把问题解决的时候那种感觉真的令人很开心。就如这道题,其实我之前做题基本都是用数组,可能大部分的问题都可以用数组解决,但是如果测试数据要求数组分配的空间很大时,这是再用数组就不行了,由于之前在总结STL的时候接触过vector但是在做题的时候并没有用过vector,而今天用vector把问题成功解决,真的让人感慨,多学点东西真的不吃亏,也许某天就用到了呢,,哈哈。
作者:你的雷哥
本文版权归作者所有,欢迎转载,但未经作者同意必须在文章页面给出原文连接,否则保留追究法律责任的权利。