逻辑闭环

题目信息

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

输入

第一行 n,m(1 ≤ n,m ≤ 300000 ) 两个数,表示事件数和线索数。
接下来 m 行,每行两个数 A,B(1 ≤ B ≤ n ) ,表示事件A能够推出事件B。

输出

一行一个数,表示最少能够用前几条线索形成逻辑闭环完成推理。若无法完成输出-1。

测试样例

5 10
1 2
2 3
3 4
4 5
1 5
2 5
3 1
1 4
1 3
2 4
7

解答

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct BiaoJi
{
    
    
    int Thing;//此处的Thing代表的意思是每个时间的结尾
    bool visit;

    BiaoJi(int Thing_, bool visit_)
    {
    
    
        Thing = Thing_;
        visit = visit_;
    }
};

vector<BiaoJi> g[300000 + 10];


struct Thing
{
    
    
public:
    int ThingA;
    int ThingB;
};

queue<int> q;

bool bfs(int a, int b)
{
    
    
    q.push(b);
    while (!q.empty())
    {
    
    
        int tmp = q.front();
        for (long i = 0; i < g[tmp].size(); i++)
        {
    
    //遍历这一行vector
            if (g[tmp][i].visit == 0)
            {
    
    //没有访问过
                if (g[tmp][i].Thing == a)
                {
    
    
                    return true;
                }
                g[tmp][i].visit = 1;
                q.push(g[tmp][i].Thing);
            }
        }
        q.pop();
    }
    return false;
}

int main()
{
    
    
    //freopen("E://test.txt", "r", stdin);
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; i++)
    {
    
    
        Thing tmp;
        cin >> tmp.ThingA >> tmp.ThingB;
        g[tmp.ThingA].push_back((BiaoJi(tmp.ThingB, 0)));
        bool ans = bfs(tmp.ThingA, tmp.ThingB);
        if (ans)
        {
    
    
            cout << i + 1 << endl;
            return 0;
        }
    }
    cout << -1 << endl;
}

猜你喜欢

转载自blog.csdn.net/zhj12399/article/details/109590122