[CF117C]Cycle
Posted lanrtabe
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF117C]Cycle相关的知识,希望对你有一定的参考价值。
题目链接:
似乎这题(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的主要内容,如果未能解决你的问题,请参考以下文章
[CF580C]Shortest Cycle(图论,最小环)