题目描述
你有一张n个点的完全图(即任意两点之间都有无向边)
现在给出这张图的两棵生成树
定义一次操作为:在任意一棵生成树中删除一条边后再加入一条边(必须在同一棵树中操作),同时需要保证操作完后仍然是一棵树
问使得两棵树相同的最少操作次数,若不存在合法的操作方案,输出-1
注意:这里的相同指的是点集与边集均相同,也就是对于第一棵树中的边(u, v),第二棵树中一定存在边(u, v)或(v, u),再不懂请看样例解释。
输入描述:
一个整数n表示无向图的点数 接下来n - 1行,每行两个整数u, v表示第一棵生成树中的边 再接下来n - 1行,每行两个整数u, v表示第二棵生成树中的边
输出描述:
一个整数,表示最少操作次数
示例1
输入
6 6 1 1 2 2 3 3 5 5 4 1 2 2 4 4 5 5 3 6 4
输出
2
说明
题目中的树如下所示
一种方案如下:
第二棵树中删除(2, 4),增加(2,3)
第二棵树中删除(4, 6),增加(1, 6)
注意:如果仅在第二棵树中删除(2, 4),增加(1, 6),得到的树虽然形态相同,但是边集不同,我们不认为它们是相同的!
示例2
输入
3 1 2 2 3 1 3 3 2
输出
1
示例3
输入
2 1 2 2 1
输出
0
备注:
2⩽n⩽1052 \leqslant n \leqslant 10^52⩽n⩽105
保证输入数据合法
思路:判断两个树中的对应顶点的边是否连通,
#include <stdio.h>
int main(){
int tree[100010],ans=0;
int n,u,v;
scanf("%d",&n);
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);//u->v点联通
tree[u]=v;
}
for(int i=0;i<n-1;i++){
scanf("%d%d",&u,&v);
if(tree[u]==v||tree[v]==u){//判断u->v是否连通
ans++;
}
}
printf("%d\n",n-1-ans);
return 0;
}