问题 D: 朋友

时间限制: 1 Sec 内存限制: 128 MB
题目描述:有一个城镇,住着n个市民。已知一些人互相为朋友。引用一个名人的话说,朋友的朋友也是朋友。意思是说如果A和B是朋友,C和B是朋友,则A和C是朋友.你的任务是数出最大朋友组的人数。输入输入第一行由N,M组成,N是市民的个数(1<=n<=30000),m是朋友对的个数(0<=m<=500000)。下面的m行每一行由两个数A和B组成(1<=A,B<=N,A<>B)表示A和B是朋友。注意给的朋友对可能会有重复。输出输出仅有一行包含一个整数,表示要求的最大朋友组的人数。
样例输入
10 12
1 2
3 1
3 4
5 4
3 5
4 6
5 2
2 1
7 10
1 2
9 10
8 9
样例输出
6
//这道题是练习并查集的基本题目,刚开始学习并查集,我也没真实搞懂,初期就先背过了学长给的代码,能够暂时解决一些题目。

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <string.h>
#include <math.h>
#include <map>
#define ll long long
#define inf 0x3f3f3f3f
#define maxn 100000
using namespace std;
int father[maxn];
int num[maxn];
void init ()
{
    for(int i=0; i<=30000; i++)
        father[i]=i;
}
int findfather(int x)//寻找祖先
{
    if(father[x]==x)
        return x;
    else
        return father[x]=findfather(father[x]);
}
void Union (int x,int y)//结合为朋友
{
    int fx=findfather(x);
    int fy=findfather(y);
    if(fx!=fy)
        father[fx]=fy;
}
bool cmp(int a,int b)//排序标准
{
    return a>b;
}
int main()
{
    int n,m,i;
    scanf("%d%d",&n,&m);
    int ans=n-1;
    int a,b;
    init();
    while(m--)
    {
        scanf("%d%d",&a,&b);
        Union(a,b);
    }
    for(i=1; i<=n; i++)
    {
        num[findfather(i)]++;
    }
    sort(num,num+maxn,cmp);
    printf("%d\n",num[0]);
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个经典的MapReduce问题,可以用Hadoop框架来实现。 首先,我们需要定义Map和Reduce函数的输入和输出格式。对于这个问题,Map函数的输入格式为一行文本,输出格式为键值对,其中键是每对共同好友,值是这对共同好友的所有朋友。Reduce函数的输入格式是一对共同好友及其所有朋友,输出格式为共同好友及其所有朋友的交集。 下面是Map和Reduce函数的实现代码: ```java public static class Map extends Mapper<LongWritable, Text, TextPair, Text> { private final TextPair pair = new TextPair(); private final Text outputValue = new Text(); @Override public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException { String[] userAndFriends = value.toString().split(":"); String user = userAndFriends[0]; String[] friends = userAndFriends[1].split(","); Arrays.sort(friends); // 排序,保证每对共同好友的顺序一致 for (int i = 0; i < friends.length - 1; i++) { for (int j = i + 1; j < friends.length; j++) { pair.set(friends[i], friends[j]); outputValue.set(user); context.write(pair, outputValue); } } } } public static class Reduce extends Reducer<TextPair, Text, TextPair, Text> { private final Text outputValue = new Text(); @Override public void reduce(TextPair key, Iterable<Text> values, Context context) throws IOException, InterruptedException { Set<String> friends = new HashSet<>(); for (Text value : values) { friends.add(value.toString()); } if (friends.size() > 1) { // 只处理有共同好友的人 outputValue.set(StringUtils.join(",", friends)); context.write(key, outputValue); } } } ``` 在Map函数中,我们对于每个用户的朋友列表,都枚举出其中两两组合。如果两个用户有共同好友,我们就把他们的名字作为键,把当前用户作为值输出。注意,在输出键值对之前,我们要对每对共同好友进行排序,这样可以保证后面Reduce函数中的同一个键的所有值都是按照同样的顺序排列的。 在Reduce函数中,我们把每个键对应的所有值放入一个集合中,并且只处理那些集合中有两个以上元素的键,也就是存在共同好友的人。对于这些键,我们把它们的所有值取交集,并把结果作为值输出。 最后,我们需要编写Driver类来设置MapReduce作业的输入输出路径等参数,并提交作业: ```java public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "find-common-friends"); job.setJarByClass(FindCommonFriends.class); job.setMapperClass(Map.class); job.setReducerClass(Reduce.class); job.setOutputKeyClass(TextPair.class); job.setOutputValueClass(Text.class); TextInputFormat.setInputPaths(job, new Path(args[0])); TextOutputFormat.setOutputPath(job, new Path(args[1])); job.waitForCompletion(true); } ``` 这里我们使用了自定义的TextPair类作为键的类型,这个类可以参考Apache WritableComparable的实现,也可以使用第三方库来简化代码。最后,我们可以在命令行中执行以下命令来运行作业: ``` hadoop jar find-common-friends.jar input output ``` 其中,input是数据文件路径,output是输出文件路径。运行完毕后,输出文件中的每一行都表示一对共同好友以及他们的所有朋友,例如: ``` A,B C,D,E,F A,C B,D,E B,C A,D,E ```

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值