码迷,mamicode.com
首页 > 其他好文 > 详细

[CF117C]Cycle

时间:2019-02-15 17:19:01      阅读:142      评论:0      收藏:0      [点我收藏+]

标签:class   bit   sizeof   lse   一个   rac   def   scanf   com   

题目链接:

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\n",i,j,k),0;
    }
    return puts("-1"),0;
}

[CF117C]Cycle

标签:class   bit   sizeof   lse   一个   rac   def   scanf   com   

原文地址:https://www.cnblogs.com/LanrTabe/p/10384524.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!