Codeforces Round #580 (Div. 2) D Shortest Cycle(最小环)

本文探讨了在给定一组数值时,如何利用Floyd算法寻找这些数值间形成的最小环。通过分析和缩小问题规模,文章提供了一种有效的解决方案,并详细展示了算法实现的代码。

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

题意:给你n个数,如果每两个数且(and)不为0,可以连无向边,求最小环。

分析:最小环可以利用Floyd来搞,n太大,如果n很小就可以直接搞了,考虑把n缩小,因为最小环是3,所有只要某一位的个数大于等于3,那么肯定结果就是3,由容斥原理(鸽巢定理)可知,当非0的个数大于63*2时,肯定会有一个位的个数大于2,或者直接统计每一位的个数也行,这样就可以把n缩小到100多了,直接跑Floyd就好了。

代码:

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N=150;
const int M=1e5+5;

ll n,cnt,ans=1e9,a[M],d[N][N],e[N][N];
int main() {
	cin>>n;
	for(int i=0; i<n; i++) {
        ll x;
		cin>>x;
		if(x) a[cnt++] = x;
	}
	if(cnt>150) {cout<<"3\n"; return 0;}
	for(int i=0; i<cnt; i++) for(int j=0; j<cnt; j++) {
		if(i!=j && a[i]&a[j]) d[i][j] = e[i][j] = 1;
		else d[i][j] = e[i][j] = 1e9;
	}
	for(int k=0; k<cnt; k++) {
		for(int i=0; i<k; i++)
            for(int j=i+1; j<k; j++)
                ans = min(ans, e[i][k] + e[k][j] + d[i][j]);
		for(int i=0; i<cnt; i++) for(int j=0; j<cnt; j++)
			d[i][j] = min(d[i][j], d[i][k] + d[k][j]);
	}
	if(ans==1e9) cout<<"-1\n";
	else cout<<ans<<endl;
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值