Codeforces Round #318-(B. Bear and Three Musketeers)

本文探讨了一个在给定的人群网络中寻找最小认识人数组合的问题,该组合必须满足特定的相互认识条件。文章详细介绍了两种解决方法:一种是通过暴力枚举来直接搜索符合条件的组合;另一种则是利用邻接表存储关系,优化搜索过程。最终目标是在不违反相互认识规则的前提下,找出认识人数最少的三人组。

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

这道题做的时候还剩下30多分钟了,于是有点慌。。。果然心理素质还是有待提高,这么水的题都没有过):导致又掉rating了。。。

题意:

现在给你n个人,m个询问,然后接下来m行告诉你a与b是相互认识的,但是这个认识不能够相互传递,也就是说a认识b,b认识c,但是a并不认识c。

然后问你是否能够在这n个人中选取3个人,使得它们认识其他人的总数最少,并且这三个人要相互认识(也就是a-b,b-c,c-a),如果不存在则输出-1

思路:

1)暴力,枚举3个人(我只能说cf的服务器好,竟然这都能够跑过去)==

2)也是暴力,但是小处理一下,把每个人认识的都相当于用邻接表的形式存下来。

1)

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
#define inf 99999999
#define maxn 4010
vector<int> G[maxn];
int num[maxn];
int e[maxn][maxn];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int a,b;
		scanf("%d%d",&a,&b);
		e[a][b]=e[b][a]=1;
		num[a]++;
		num[b]++;
		G[a].push_back(b);
		G[b].push_back(a);
	}
	int lmin=inf;
	for(int i=1;i<=n;i++){
		int nn=0,a,b,c;
		for(int j=0;j<G[i].size();j++){
			b=G[i][j];
			for(int k=0;k<G[b].size();k++){	//一开始这里写成了G[j].size(),结果一直错!! 
				a=i; b=G[i][j]; c=G[b][k];
				if(e[a][b]&&e[b][c]&&e[c][a]){
					nn=num[a]+num[b]+num[c];
					lmin=min(lmin,nn-6);
				}
			}
		}
	}
	if(lmin==inf) printf("-1\n");
	else printf("%d\n",lmin);
}


2)

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<math.h>
#include<vector>
using namespace std;
#define inf 99999999
#define maxn 4010
vector<int> G[maxn];
int vis[maxn][maxn];
int a[maxn],b[maxn];
int main(){
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		scanf("%d%d",&a[i],&b[i]);
		G[a[i]].push_back(b[i]);
		G[b[i]].push_back(a[i]);
		vis[a[i]][b[i]]=vis[b[i]][a[i]]=1;
	}
	int lmax=inf;
	for(int i=1;i<=m;i++){
		int u=a[i],v=b[i];
		if(G[u].size()>=2&&G[v].size()>=2){
			for(int j=0;j<G[v].size();j++){
				int w=G[v][j];
				if(vis[u][v]&&vis[v][w]&&vis[w][u]){
					int ans=G[u].size()+G[v].size()+G[w].size()-6;
					lmax=min(lmax,ans);
				}
			}
		}
	}
	if(lmax==inf) printf("-1\n");
	else printf("%d\n",lmax);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值