【CodeForces - 574B】Bear and Three Musketeers (枚举边,思维,优秀暴力)

题干:

Do you know a story about the three musketeers? Anyway, you will learn about its origins now.

Richelimakieu is a cardinal in the city of Bearis. He is tired of dealing with crime by himself. He needs three brave warriors to help him to fight against bad guys.

There are n warriors. Richelimakieu wants to choose three of them to become musketeers but it's not that easy. The most important condition is that musketeers must know each other to cooperate efficiently. And they shouldn't be too well known because they could be betrayed by old friends. For each musketeer his recognition is the number of warriors he knows, excluding other two musketeers.

Help Richelimakieu! Find if it is possible to choose three musketeers knowing each other, and what is minimum possible sum of their recognitions.

Input

The first line contains two space-separated integers, n and m (3 ≤ n ≤ 4000, 0 ≤ m ≤ 4000) — respectively number of warriors and number of pairs of warriors knowing each other.

i-th of the following m lines contains two space-separated integers ai and bi (1 ≤ ai, bi ≤ nai ≠ bi). Warriors ai and bi know each other. Each pair of warriors will be listed at most once.

Output

If Richelimakieu can choose three musketeers, print the minimum possible sum of their recognitions. Otherwise, print "-1" (without the quotes).

Examples

Input

5 6
1 2
1 3
2 3
2 4
3 4
4 5

Output

2

Input

7 4
2 1
3 6
5 1
1 7

Output

-1

Note

In the first sample Richelimakieu should choose a triple 1, 2, 3. The first musketeer doesn't know anyone except other two musketeers so his recognition is 0. The second musketeer has recognition 1 because he knows warrior number 4. The third musketeer also has recognition 1 because he knows warrior 4. Sum of recognitions is 0 + 1 + 1 = 2.

The other possible triple is 2, 3, 4 but it has greater sum of recognitions, equal to 1 + 1 + 1 = 3.

In the second sample there is no triple of warriors knowing each other.

题目大意:

给你n个人和m个关系,(a,b)表示a和b认识,现在这个人想雇佣其中3个人,

1: 这3个人必须相互认识

2: 这3个人的识别度的总和最小(一个人的识别度为:除了另外两人认识的人的数,三个人的识别度相加最小)

解题报告:

    显然,2000ms的时限,4000的数据量,考虑是否o(n^2)可以解决。(其实这题直接枚举三个点,o(n^3)也可以过?)怎么优化到平方级别呢?其实也很简单,就是第一层循环遍历m条边就好了。因为你三层for枚举顶点的时候,其实前两层有很多是浪费掉了的,因为有很多顶点的之间根本没有边,而你都遍历了一遍,所以我们都记录下来边了,为什么不直接遍历边呢?这样我们就有两个顶点了呀,然后再来一层循环遍历每一个点就好了。注意这种暴力的题一定别忘判断一下是否遍历到了自己,比如【CodeForces - 761C】Dasha and Password 这道题,最开始就忘了判断是否遍历到了同一个字符串。

AC代码:

#include<bits/stdc++.h>

using namespace std;
const int MAX = 4000 + 5 ;
int du[MAX];
bool maze[MAX][MAX];
int head[MAX];
struct Edge {
	int fm,to;
	int w;
}e[50000 + 5];
int top;
void add(int u,int v) {
	e[++top].fm = u;
	e[top].to = v;
}
int main()
{
	int n,m,u,v;
	cin>>n>>m;
	for(int i = 1; i<=m; i++) {
		scanf("%d%d",&u,&v);
		add(u,v);add(v,u);
		du[u]++;du[v]++;
		maze[u][v] = maze[v][u] = 1;
	}
	int ans = 0x3f3f3f3f;
	for(int i = 1; i<=top; i++) {
		for(int j = 1; j<=n; j++) {
			if(j == e[i].fm || j == e[i].to) continue;
			if(maze[e[i].fm][j] && maze[e[i].to][j]) {
				ans = min(ans,du[e[i].to] + du[e[i].fm] + du[j]);
			}
		}
	}
	if(ans == 0x3f3f3f3f) puts("-1");
	else printf("%d\n",ans-6);
	return 0 ;
 } 

再来一个代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int inf = 0x3f3f3f3f;
const int maxn = 4050;
 
int n,m,d[maxn];
bool g[maxn][maxn];
//一开始以为暴力的话是n^3会超时,后来看了题解原来前两层放上去之后加个剪枝,第三层的复杂度是加上去的而不是乘上去的 
//即剪枝使得复杂度由O(N^3)降为O(N^2+NM) 
int main(){//62 ms	18100 KB
    int x,y;
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;++i){
    	scanf("%d%d",&x,&y);
    	g[x][y]=g[y][x]=1;
		d[x]++;
		d[y]++; 
    }
    int ans=inf;
	for(int i=1;i<=n;++i){
		for(int j=1;j<=n;++j){
			if(g[i][j] && d[i]+d[j]<=inf){//只有M个g[i][j]成立  
				for(int k=1;k<=n;++k){
					if(g[i][k] && g[j][k]){
						ans=min(ans,d[i]+d[j]+d[k]);
					}
				}
			}
		}
	}
	//相当于外面枚举N^2次,对于其中的M次才有第三层for 故复杂度为 O(N^2+M*N) 
	if(ans>=inf) puts("-1");
	else printf("%d\n",ans-6);
    return 0;
}

 

 

 

AC代码2:(其实也不是拓扑排序啦,就是用vector表示了二维数组,并且,由第二个点找第三个点的时候直接在第一个点所连的边中找就可以了。但是那个c函数其实也有点消耗时间?如果直接用个bool类型的maze二维数组来表示无向图两点之间是否相连就更快了)

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值