[题解]CF117C Cycle

思路

发现最简单的方法就是直接枚举三个点,但是复杂度 Θ(n3) 无法接受。

考虑枚举一个点,并确定它的一条边,那么只需要再枚举一个点了。于是转化为了,对于每一个点找到其最好的出边。

观察下图,ac 的边是不必要的。因为,如果有一个三元环包含 ac,那么一定能找到一个不包含 ac 的一条边。

那么,把这种边全部删除,每一个点都将只剩下一条出边,然后枚举另一个点即可。

Code

#include <bits/stdc++.h>
#define re register

using namespace std;

const int N = 5010;
int n,to[N];
char arr[N][N];

inline int read(){
    int r = 0,w = 1;
    char c = getchar();
    while (c < '0' || c > '9'){
        if (c == '-') w = -1;
        c = getchar();
    }
    while (c >= '0' && c <= '9'){
        r = (r << 3) + (r << 1) + (c ^ 48);
        c = getchar();
    }
    return r * w;
}

int main(){
    n = read();
    for (re int i = 1;i <= n;i++) scanf("%s",arr[i] + 1);
    for (re int i = 1;i <= n;i++){
        for (re int j = 1;j <= n;j++){
            if (arr[i][j] == '1' && (!to[i] || arr[j][to[i]] == '1')) to[i] = j;
        }
    }
    for (re int i = 1;i <= n;i++){
        for (re int j = 1;j <= n;j++){
            if (arr[to[i]][j] == '1' && arr[j][i] == '1') return printf("%d %d %d",i,to[i],j),0;
        }
    }
    puts("-1");
    return 0;
}

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18322815

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示