题目信息
小张是一位推理迷,他非常喜欢看侦探小说与侦探电影。同时他也会玩一些推理游戏,在侦探游戏中,小张需要发掘事件之间的联系。通过一条线索,他能够通过事件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;
}