[ZOJ 3710] Friends

博客给出题目链接,介绍判断两人能否成为朋友的思路。用vector记录朋友关系,set筛选非共同朋友数量,计算共同朋友数量并与k比较,大于k则可成朋友。新关系形成后需重新遍历,直至无朋友可交,还给出AC代码链接。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3710

说下思路:
用vector记录每个人所结交的朋友,利用set的特性(不能存在重复元素)筛选出不是两个人共同的朋友的数量,然后 x结交的朋友的数量 + y结交的朋友的数量 - x与y非共同朋友的数量 得出一个值(x与y共同朋友的数量),然后和k进行比较,大于k说明两人可以在以后成为朋友。要注意,当x与y成为新的朋友后,原先的关系会改变,需要从头再遍历一遍,如此循环往复,直到没有朋友可交为止。

AC代码:

#include <cstdio>
#include <set>
#include <vector>
#include <cstring>

using namespace std;

const int maxn = 110;

vector<int> v[maxn];
set<int> s;
bool vis[maxn][maxn];

int test;
int n, m, k;
int x, y;

bool judge(int x, int y) {
    s.clear();
    for(int i = 0; i < v[x].size(); i++) {
        s.insert(v[x][i]);
    }
    for(int i = 0; i < v[y].size(); i++) {
        s.insert(v[y][i]);
    }
    int temp = v[x].size() + v[y].size() - s.size();
    if(temp >= k)
        return true;
    return false;
}

void init() {
    memset(vis, false, sizeof(vis));
    //清空要清空所有分配的内存,也就是要到maxn,不然可能会导致段错误(Segmentation Fault)
    for(int i = 0; i < maxn; i++) {
        vis[i][i] = true;
        v[i].clear();
    }
}

int main() {
    scanf("%d", &test);
    while(test--) {
        init();
        scanf("%d%d%d", &n, &m, &k);
        for(int i = 0; i < m; i++) {
            scanf("%d%d", &x, &y);
            v[x].push_back(y);
            v[y].push_back(x);
            vis[x][y] = vis[y][x] = true;
        }
        bool flag = true;
        int cnt = 0;
        while(flag) {
            flag = false;
            for(int i = 0; i < n; i++) {
                for(int j = i + 1; j < n; j++) {
                    if(!vis[i][j]) {
                        if(judge(i, j)) {
                            flag = true;
                            vis[i][j] = vis[j][i] = true;
                            v[i].push_back(j);
                            v[j].push_back(i);
                            cnt++;
                        }
                    }
                }
            }
        }
        printf("%d\n", cnt);
    }
    return 0;
}

转载于:https://www.cnblogs.com/youpeng/p/10802407.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值