24. 逻辑闭环

小张是一位推理迷,他非常喜欢看侦探小说与侦探电影。同时他也会玩一些推理游戏,在侦探游戏中,小张需要发掘事件之间的联系。通过一条线索,他能够通过事件A推理出事件B。如果通过某一个事件A能够推出事件A本身,那么他就能够完成推理。现在按照顺序给出m条线索,请你算出他最少能够用前几条线索能够形成逻辑闭环完成推理。

解题思路:

题目中的隐藏性质:如果加上当前边便有了一条回路,又因为前面边中没有回路,就说明回路中必然有新加进来的两个点,这样的话我们就从新加边的终点向起点搜索,如果能搜到,那么就有回路,否则继续加边。

之后又看了一个巨佬的题解,发现只需要判断环存在即可,不需要添加负环这样的性质,于是二分答案加tarjan判断环即可,或者利用拓朴排序,判断即可

代码:

#include <cstdio>  
#include <cstring>  
#include <iostream>  
#include <algorithm>  
#include <queue>  
using namespace std;  
  
typedef long long LL;  
const int N = 300010, M = 300010;  
int n, m;  
int h[N], e[M], w[M], ne[M], idx;  
LL dist[N];  
int q[N], cnt[N];  
  
void add(int a, int b, int c)  
{  
    e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;  
}  
bool bfs(int x ,int y){  
    queue<int> q;  
    bool st[N];  
    q.push(x);  
    while(q.size()){  
        int t=q.front();  
        if(t==y)return 1;  
        q.pop();  
        for(int i=h[t];~i;i=ne[i]){  
            int v=e[i];  
            q.push(v);  
        }  
    }  
    return 0;  
}  
int main()  
{  
    ios::sync_with_stdio(false);  
    cin.tie(0);  
    cout.tie(0);  
    cin>>n>>m;  
    memset(h, -1, sizeof h);  
    for (int i = 1; i <= m; i ++ )  
    {  
        int a, b;  
        cin>>a>>b;  
        add(a,b, 1);  
        if(bfs(b,a)){  
            cout<<i<<endl;return 0;}  
    }  
cout<<-1<<endl;  
    return 0;  
}  

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值