D. Shortest Cycle(鸽巢原理 + floyd求最小环)

题目链接————

题目大意是给你一个节点数列,每一个数代表一个节点,若两个数按位与不等于零,则两个点之间有一个长度为 一的无向边,问可以形成的最小环是多少。

思路:看别人博客一直不懂为什么大于128就输出3,今天看了CF评论区,有个dalao讲的太好了。

I did it this way- The maximum number in the input is 10^18 which can be represented in 64 bits. The minimum possible cycle can be of length 3. If we have the xth bit set in any 3 numbers, then we are done! (all 3 will be mutually connected because of non zero "and") There are at max 64 bits. => If we have more than 128 non zero numbers (By PHP) in the array, then we will get a cycle of length 3.Now for <= 128 non zero numbers. We can check by actually making a graph. It will take O(m^2), which will be well within the bounds.

翻译:

我是这样做的 - 输入中的最大数量是10 ^ 18,可以用64位表示。 最小可能周期长度为3.如果我们在任何3个数字中设置了第x位,那么我们就完成了! (由于非零“和”,所有3将相互连接)最多64位。 =>如果数组中有超过128个非零数字(按PHP),那么我们将得到一个长度为3的循环。

 

现在<= 128非零数字。 我们可以通过实际制作图表来检查。 它将需要O(m ^ 2),这将在范围内。

 

他解释到

10 ^ 18非常适合64位。 我们在任何公共位置都需要至少3个设置位。 通过Pigeon Hole原理如果我们有超过64 * 2 = 128个数字(非零,因为零没有设置任何位),那么至少有一个位置将有3个设置位。 (如果计算表示10 ^ 18所需的确切位数,则可以使128的界限更严格)

 

厉害

接下来说下我在做这个题目时遇到的坑,首先“无穷大”是相对的,要根据数据范围恰当的设置,然后要想到0与任何数&都是零所以没有必要管它,所以数组里只需要存大于0的数就行。不然初始化会T。。。

然后不是零的数大于128就可以直接输出3了。

我的AC Code:

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LL long long
#define ULL unsigned  long long
#define maxn (LL)1e7
#define INF 0x3f3f3f3f
#define inf 0x7fffffff
#define PI  acos(-1.0)
#define pb push_back
#define re register LL
const double eps = 0.0000001;
using namespace std;
typedef pair pii;
inline LL sgn(double x)
{
    return (x > eps) - (x < -eps);
}
LL n,m;
LL ans[maxn+5];
LL dis[200][200],Map[200][200];
void init(LL x)
{
    for(int i =1 ; i<=x; ++i)
        for(int j = 1; j<=x; ++j)
            dis[i][j] = Map[i][j] = INF;
}
int main()
{
    ios::sync_with_stdio(false);
    cin>>n;
    LL cnt= 1;
    LL t;
    for(int i = 1; i<=n; ++i)
    {
        cin>>t;
        if(t)
        {
            ans[cnt++] = t;
            if(cnt>128)
                return cout<<3,0;
        }
    }
    init(cnt+3);
    for(int i = 1; i1e9)
        cout<<-1<

CFdalao的AC Code:

#include 
#include 
#define N 135
using namespace std;
typedef long long ll;

ll n, cnt, mn=1e9, a[N], d[N][N], e[N][N];
int main()
{
    ll i, j, k, t;
    cin>>n;
    for(i=0; i128)
                break;
        }
    }
    if(i

 

 

你可能感兴趣的:(图论——最短路,数论,codeforce)