[CF117C]Cycle

Posted lanrtabe

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF117C]Cycle相关的知识,希望对你有一定的参考价值。

题目链接:

CF117C

Luogu Remote Judge

似乎这题(DFS)可过。。我就是饿死也不会用DFS

我们考虑最暴力的做法:枚举(3)个点判断是否形成环。

但是(O(n^3))是肯定过不了的。

那么先枚举前(2)个点,就要判断第(2)个点出发有没有一个点和第(1)个点联通。

先预处理哪些点和第(1)个点联通,那么就是求第(2)个点能够到达的点集和能够到达第(1)个点的点集有没有交集。

这里用bitset优化即可。

时间复杂度 (O(frac{n^3}{32}))

bitset要手写,(STL)的常数太大了。

代码:

#include <cstdio>
#include <cstring>
typedef unsigned long long ull;

struct Bitset
{
    ull a[80];

    inline void Set(const int x){a[x>>6]|=1ull<<(x&63);}//将第x位设为1

    inline bool Get(const int x){return a[x>>6]>>(x&63)&1;}//获取第x位的值

    inline bool Match(const Bitset &b)//判断和b是否有交集
    {
        for(int i=0;i<80;++i)
            if(a[i]&b.a[i])return true;
        return false;
    }

    inline void Clear(){memset(a,0,sizeof a);}//清空
};

int n;
char s[5005];
Bitset g[5005],a;

int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;++i)
    {
        scanf("%s",s+1);
        for(int j=1;j<=n;++j)
            if(s[j]&1)g[i].Set(j);
    }
    for(int i=1;i<=n;++i)
    {
        a.Clear();
        for(int j=1;j<=n;++j)
            if(g[j].Get(i))
                a.Set(j);
        for(int j=1;j<=n;++j)
            if(g[i].Get(j))
                if(g[j].Match(a))
                    for(int k=1;k<=n;++k)//有解,暴力找解。
                        if(g[j].Get(k)&&g[k].Get(i))
                            return printf("%d %d %d
",i,j,k),0;
    }
    return puts("-1"),0;
}

以上是关于[CF117C]Cycle的主要内容,如果未能解决你的问题,请参考以下文章

CodeForce 117C Cycle DFS

CF932C Permutation Cycle

[CF580C]Shortest Cycle(图论,最小环)

[cf557d]Vitaly and Cycle(黑白染色求奇环)

nginx坑记录

如何从后台弹出片段