177 lines
3.5 KiB
C++
177 lines
3.5 KiB
C++
|
#include <stdio.h>
|
||
|
#include <vector>
|
||
|
using namespace std;
|
||
|
unsigned short *neighbors[65540];
|
||
|
unsigned short bfsGraph[65540] = {0}; // index: to value: from
|
||
|
unsigned short outDegrees[65540] = {0};
|
||
|
unsigned short inDegrees[65540] = {0};
|
||
|
int nodeNum, destroyed;
|
||
|
template <typename T>
|
||
|
class Queue
|
||
|
{
|
||
|
public:
|
||
|
Queue(int max);
|
||
|
Queue(Queue &q);
|
||
|
~Queue();
|
||
|
bool isEmpty();
|
||
|
void in(T t);
|
||
|
T out();
|
||
|
|
||
|
private:
|
||
|
T *list;
|
||
|
int max, front, tail;
|
||
|
bool empty = true;
|
||
|
};
|
||
|
template <typename T>
|
||
|
Queue<T>::Queue(int max)
|
||
|
{
|
||
|
list = new T[this->max = max];
|
||
|
front = 0;
|
||
|
tail = -1;
|
||
|
}
|
||
|
template <typename T>
|
||
|
Queue<T>::Queue(Queue &q)
|
||
|
{
|
||
|
list = new T[max = q.max];
|
||
|
front = 0;
|
||
|
tail = -1;
|
||
|
for (int i = front; (i > front && tail < front) || i <= tail; (i++) % max)
|
||
|
{
|
||
|
list[++tail] = q.list[i];
|
||
|
}
|
||
|
if (!q.isEmpty)
|
||
|
empty == false;
|
||
|
}
|
||
|
template <typename T>
|
||
|
Queue<T>::~Queue()
|
||
|
{
|
||
|
delete[] list;
|
||
|
}
|
||
|
template <typename T>
|
||
|
bool Queue<T>::isEmpty()
|
||
|
{
|
||
|
return empty;
|
||
|
}
|
||
|
template <typename T>
|
||
|
void Queue<T>::in(T t)
|
||
|
{
|
||
|
if (tail == (front - 1 + max) % max && !empty)
|
||
|
{
|
||
|
throw 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
tail++;
|
||
|
tail = tail % max;
|
||
|
list[tail] = t;
|
||
|
empty = false;
|
||
|
}
|
||
|
}
|
||
|
template <typename T>
|
||
|
T Queue<T>::out()
|
||
|
{
|
||
|
if (empty)
|
||
|
{
|
||
|
throw 0;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (front == tail)
|
||
|
empty = true;
|
||
|
int tmp = front;
|
||
|
front++;
|
||
|
front = front % max;
|
||
|
return list[tmp];
|
||
|
}
|
||
|
}
|
||
|
bool bfs(int nodeNum, unsigned short delFrom = 0, unsigned short delTo = 0, bool output = false)
|
||
|
{
|
||
|
Queue<unsigned short> q(65540);
|
||
|
bool reached[65540] = {0};
|
||
|
q.in(0);
|
||
|
reached[0] = true;
|
||
|
while (1)
|
||
|
{
|
||
|
if (q.isEmpty())
|
||
|
{
|
||
|
break;
|
||
|
}
|
||
|
int current = q.out();
|
||
|
for (int i = 0; i < outDegrees[current]; i++)
|
||
|
{
|
||
|
if (current == delFrom && neighbors[current][i] == delTo)
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
if (reached[neighbors[current][i]])
|
||
|
{
|
||
|
continue;
|
||
|
}
|
||
|
reached[neighbors[current][i]] = true;
|
||
|
q.in(neighbors[current][i]);
|
||
|
if (output)
|
||
|
{
|
||
|
bfsGraph[neighbors[current][i]] = current;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
for (int i = 0; i < nodeNum; i++)
|
||
|
{
|
||
|
if (!reached[i])
|
||
|
{
|
||
|
return false;
|
||
|
}
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
int main()
|
||
|
{
|
||
|
scanf("%d %d", &nodeNum, &destroyed);
|
||
|
for (int i = 0; i < nodeNum; i++)
|
||
|
{
|
||
|
int outDegNum;
|
||
|
scanf("%d", &outDegNum);
|
||
|
int currentNode = i;
|
||
|
outDegrees[i] = outDegNum;
|
||
|
neighbors[i] = new unsigned short[outDegNum];
|
||
|
for (int i = 0; i < outDegNum; i++)
|
||
|
{
|
||
|
int nodeNo;
|
||
|
scanf("%d", &nodeNo);
|
||
|
inDegrees[nodeNo] += 1;
|
||
|
neighbors[currentNode][i] = nodeNo;
|
||
|
}
|
||
|
}
|
||
|
bool connected = bfs(nodeNum, 0, 0, true);
|
||
|
if (connected)
|
||
|
{
|
||
|
printf("1\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
for (int i = 0; i < destroyed + 1; i++)
|
||
|
printf("0\n");
|
||
|
return 0;
|
||
|
}
|
||
|
for (int i = 0; i < destroyed; i++)
|
||
|
{
|
||
|
int from, to;
|
||
|
scanf("%d %d", &from, &to);
|
||
|
if (bfsGraph[to] != from)
|
||
|
{
|
||
|
printf("1\n");
|
||
|
}
|
||
|
else if (inDegrees[to] <= 1)
|
||
|
{
|
||
|
printf("0\n");
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if (bfs(nodeNum, from, to, false))
|
||
|
printf("1\n");
|
||
|
else
|
||
|
printf("0\n");
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|