头条红人问题解法

头条红人问题解法

9.9日头条算法笔试题第5题。
题目描述
抖音红人:假设用户数为N,有M个关注关系对(A,B).(A,B)表示用户A关注了用户B。关注关系具有传递性。即A关注B,B关注C,那么A也关注C。同时关注的递归传递层数不止2层,可以无限递归。默认自己已经关注了自己,如果输入N=1,则输出也为1。
如果一个用户被所有N个用户直接或间接关注。那么我们认为这个用户是抖音红人。求抖音红人的个数。


用map和set的组合来存储每个人的粉丝群体。`

//递归被关注
void recurFollow(int curId, map<int, set<int>>& fansRelation, vector<bool>& flag,set<int>& tmp)
{
    //如果该id没有fans,即一开始就没有将该id录入到fansRelation的表中,在fansRelation的表中就不会找到curId,此时跳出递归
    if (fansRelation.find(curId) == fansRelation.end())
    {
        tmp.insert(curId);
        flag[curId] = true;
        return;
    }
    for (int fansId : fansRelation[curId])
    {
        if (fansId==curId) continue;//遍历自己的情况
        if (flag[fansId-1] == true) continue;//标记过的结点不再遍历
        tmp.insert(fansId);
        flag[fansId-1] = true;//将当前节点进行标记
        recurFollow(fansId, fansRelation, flag, tmp);
        for (int i : tmp)  fansRelation[curId].insert(i);//将tmp中的id全部放入当前id的粉丝群中
    }
}
int isHot( map<int, set<int>>& fansRelation, vector<bool>& flag,int N)
{
    int count=0;
    set<int> tmp;
    for (map<int, set<int>>::iterator it= fansRelation.begin();it!=fansRelation.end();it++)
    {
        for (int i=0;i<N;i++)   flag[i] = false;//每次以下一个基点开始遍历时,需要将flag重置
        recurFollow(it->first, fansRelation, flag, tmp);
        tmp.clear();//清空tmp以备下次使用。
    }
    //判断有几个人的粉丝量达到了N
    for (map<int, set<int>>::iterator it = fansRelation.begin(); it != fansRelation.end(); it++) if (it->second.size() == N) count++;
    return count;
}

int main()
{
    int N, M;
    cin >> N >> M;
    //存放用户id和其关注的人
    //map<int, set<int>> following;
    //用户id和关注他的人
    map<int, set<int>> beFollowed;
    //存放关系对
    vector<vector<int>> fellowPair(M, vector<int>(2));
    //标记该节点是否被遍历过
    vector<bool> flag(N, false);
    for (int i=0;i<M;i++)
    {
        for (int j=0;j<2;j++)
        {
            cin >> fellowPair[i][j];
        }
        //following[fellowPair[i][0]].insert(fellowPair[i][1]);
        beFollowed[fellowPair[i][1]].insert(fellowPair[i][0]);
        beFollowed[fellowPair[i][1]].insert(fellowPair[i][1]);//默认自己是自己的粉丝
    }
    cout<<isHot(beFollowed, flag,N);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值