Description
You are given two trees of
N
nodes each,
How many simple cycles of length 4 are there in the resulting graph?
Standard input
The first line contains N.
The next
The next N−1 lines contain two integers, denoting an edge from T2 .
Standard output
Print the answer on the first line.
Constraints and notes
- 1
≤
N
≤ 105 - Throughout the whole problem, 1-based indexing of the nodes is considered.
sample input
4
1 2
1 3
3 4
3 1
1 4
2 4
sample output
1
Explanation
The red nodes are from the second tree.
The cycle is 1 1 3 3
题意:有两棵树
T1
,
T2
都有
N
个结点,除了每棵树本身的边以外,还有一些额外的边把两棵树相同标号的结点连起来。求形成的图中四元环的个数。
思路:树本身是没有环的,所以四元环只能建立在两棵树之间的,而两棵树之间的边只连接编号相同的结点,因此所有的四元环只可能是a a b b型的,只需要检查所有的a a b b是否相连即可,但还可以优化。
已经知道四元环是a a b b型的,还知道所有相同的点都已经被连接起来,所以只需要检查是否
我采用的方法是用向量数组把树 T1 先存下来,再去检查树 T2 的边在 T1 中是否存在。根据上面的分析,如果存在,那么就有且仅有一个四元环;如果不存在,那么这条边一定不能和其他边构成四元环。
#include<stdio.h>
#include<vector>
#define maxn 100000
using std::vector;
int n;
vector<int> t1[maxn+5];// 省掉一个t2[maxn+5]数组和输入
int main() {
int l, r;
int ans = 0;
scanf("%d", &n);
for (int i = 0; i < n-1; ++i) {
scanf("%d %d", &l, &r);
if (l > r) {
l = l + r;
r = l - r;
l = l - r;
}//默认编号小的结点做大的结点的父亲
t1[l].push_back(r);//把r加入到l的子节点向量容器中
}
for (int i = 0; i < n-1; ++i) {
scanf("%d %d", &l, &r);
if (l > r) {
l = l + r;
r = l - r;
l = l - r;
}//默认编号小的结点做大的结点的父亲
//t2[l].push_back(r);
bool aring = false;
for (int t = 0; t < t1[l].size()&å==false; ++t) {
//要在T1中找边l-r,只需要检查l的所有子节点即可
if (t1[l][t] == r)//并不是二维数组,可以去看一下向量容器的使用
aring = true;
}
if (aring)++ans;
}
printf("%d", ans);
}