牛可乐发红包脱单ACM赛$A题

题目:

链接: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.

  1.  
  2. #include<cstdio>
  3. #include<iostream>
  4. #include<algorithm>
  5. #include<string>
  6. #include<cmath>
  7. #include<map>
  8. #define maxn 100000
  9. using namespace std;
  10. typedef long long ll;
  11. map<pair<int, int>, bool> mp;
  12. int main(){
  13.     int N;
  14.     scanf("%d",&N);
  15.     int x,y;
  16.     for(int i=1;i<=N-1;i++){
  17.         cin>>x>>y;
  18.         mp[make_pair(x,y)]=1;
  19.         mp[make_pair(y,x)]=1;
  20.     }
  21.     int ans=0;
  22.     for(int i=1;i<=N-1;i++){
  23.         cin>>x>>y;
  24.         if(mp.find(make_pair(x,y))==mp.end()&&mp.find(make_pair(y,x))==mp.end())ans++;
  25.     }
  26.     printf("%d",ans);
  27.     return 0;
  28. }
  1. 代码2.
  2.  
  3. #include<cstdio>
  4. #include<iostream>
  5. #include<algorithm>
  6. #include<string>
  7. #include<cmath>
  8. #include<vector>
  9. #include<map>
  10. #define maxn 100000
  11. using namespace std;
  12. typedef long long ll;
  13.  
  14. vector<int> v[100005];
  15.  
  16. int main()
  17. {
  18.     int n;
  19.     scanf("%d",&n);
  20.     int s,t;
  21.     for(int i=1;i<n;i++){
  22.         scanf("%d%d",&s,&t);
  23.         v[s].push_back(t);
  24.         v[t].push_back(s);
  25.     }
  26.     int ans=0,sum;
  27.     for(int i=1;i<n;i++){
  28.         scanf("%d%d",&s,&t);
  29.         sum=count(v[s].begin(),v[s].end(),t);
  30.         if(sum == 0)
  31.             ans++;
  32.     }
  33.  
  34.     printf("%d\n",ans);
  35.     return 0;
  36. }
     

 

ACM/ICPC(ACM International Collegiate Programming Contest, 国际大学生程序设计竞)是由国际计算机界历史悠久、颇具权威性的组织ACM(Association for Computing Machinery,国际计算机协会)主办的,世界上公认的规模最大、水平最高的国际大学生程序设计竞,其目的旨在使大学生运用计算机来充分展示自己分析问和解决问的能力。该项竞从1970年举办至今已历29届,一直受到国际各知名大学的重视,并受到全世界各著名计算机公司的高度关注,在过去十几年中,APPLE、AT&T、MICROSOFT和IBM等世界著名信息企业分别担任了竞的赞助商。可以说,ACM国际大学生程序设计竞已成为世界各国大学生最具影响力的国际级计算机类的事,是广大爱好计算机编程的大学生展示才华的舞台,是著名大学计算机教育成果的直接体现,是信息企业与世界顶尖计算机人才对话的最好机会。   该项竞分区域预和国际决两个阶段进行,各预区第一名自动获得参加世界决的资格,世界决安排在每年的3~4月举行,而区域预安排在上一年的9~12月在各大洲举行。   ACM/ICPC的区域预是规模很大、范围很广的事。仅在2003年参加区域预的队伍就有来自75个国家(地区),1411所大学的3150支代表队,他们分别在127个场中进行比,以争夺全球总决的73个名额,其激烈程度可想而知。 2005年第30届ACM/ICPC亚洲区预共设了北京、成都、汉城、东京等11个站,来自亚洲各国知名高校的各个代表队进行了激烈的角逐。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值