[ZOJ 3710] Friends
Posted youpeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[ZOJ 3710] Friends相关的知识,希望对你有一定的参考价值。
题目链接: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;
}
以上是关于[ZOJ 3710] Friends的主要内容,如果未能解决你的问题,请参考以下文章
ZOJ What Kind of Friends Are You?
zoj 3960 What Kind of Friends Are You?(哈希)
ZOJ 3960 What Kind of Friends Are You?(读题+思维)