CS Round#65 B Count 4-cycles

Description

You are given two trees of N nodes each, T1 and T2 . Suppose N additional bidirectional edges are added: the ith edge will join nodes i from T1 and i from T2 , for every 1 i N .

How many simple cycles of length 4 are there in the resulting graph?

Standard input

The first line contains N.

The next N1 lines contain two integers, denoting an edge from T1 ​​.

The next N1 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
example

题意:有两棵树 T1 , T2 都有 N 个结点,除了每棵树本身的边以外,还有一些额外的边把两棵树相同标号的结点连起来。求形成的图中四元环的个数。
思路:树本身是没有环的,所以四元环只能建立在两棵树之间的,而两棵树之间的边只连接编号相同的结点,因此所有的四元环只可能是a a b b型的,只需要检查所有的a a b b是否相连即可,但还可以优化。
已经知道四元环是a a b b型的,还知道所有相同的点都已经被连接起来,所以只需要检查是否T1的a b和 T2 的a 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()&&aring==false; ++t) {
        //要在T1中找边l-r,只需要检查l的所有子节点即可
            if (t1[l][t] == r)//并不是二维数组,可以去看一下向量容器的使用
            aring = true;
        }
        if (aring)++ans;

    }
    printf("%d", ans);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值