题目:
链接:https://ac.nowcoder.com/acm/contest/223/A
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld题目描述
你有一张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备注:
保证输入数据合法
思路:
对于一条没有同时出现的边,我们至少需要一次操作来使其同时出现。那么我们只要统计两棵树中有多少不同的边即可
关键是如何去判断,那么我们就有两种思路:
1.map<pair<int, int>, bool> mp;
顺便了解了pair和map_pair的用法:
pair是将2个数据组合成一个数据,当需要这样的需求时就可以使用pair,使用pair的构造函数也可以使用make_pair来生成我们需要的pair。 一般make_pair都使用在需要pair做参数的位置,可以直接调用make_pair生成pair对象。
寻找是否存在:
不存在:if(mp.find(make_pair(x,y))==mp.end())返回1,否则返回0
2.
vector<
int
> v[100005];
count函数: 返回元素值为t的元素个数。
count(v[s].begin(),v[s].end(),t)
代码:1.
- #include<cstdio>
- #include<iostream>
- #include<algorithm>
- #include<string>
- #include<cmath>
- #include<map>
- #define maxn 100000
- using namespace std;
- typedef long long ll;
- map<pair<int, int>, bool> mp;
- int main(){
- int N;
- scanf("%d",&N);
- int x,y;
- for(int i=1;i<=N-1;i++){
- cin>>x>>y;
- mp[make_pair(x,y)]=1;
- mp[make_pair(y,x)]=1;
- }
- int ans=0;
- for(int i=1;i<=N-1;i++){
- cin>>x>>y;
- if(mp.find(make_pair(x,y))==mp.end()&&mp.find(make_pair(y,x))==mp.end())ans++;
- }
- printf("%d",ans);
- return 0;
- }
- 代码2.
- #include<cstdio>
- #include<iostream>
- #include<algorithm>
- #include<string>
- #include<cmath>
- #include<vector>
- #include<map>
- #define maxn 100000
- using namespace std;
- typedef long long ll;
- vector<int> v[100005];
- int main()
- {
- int n;
- scanf("%d",&n);
- int s,t;
- for(int i=1;i<n;i++){
- scanf("%d%d",&s,&t);
- v[s].push_back(t);
- v[t].push_back(s);
- }
- int ans=0,sum;
- for(int i=1;i<n;i++){
- scanf("%d%d",&s,&t);
- sum=count(v[s].begin(),v[s].end(),t);
- if(sum == 0)
- ans++;
- }
- printf("%d\n",ans);
- return 0;
- }