As part of a CS course,Alice just finished programming her robot to explore a graph having nn nodes,labeled 1,2,...,n,1,2,...,n, and mm directed edges. Initially the robot starts at node 11.
While nodes may have several outgoing edges, Alice programmed the robot so that any node may have a forced move to a specific one of its neighbors. For example, it may be that node 55 has outgoing edges to neighbors 1, 41,4, and 66 but that Alice programs the robot so that if it leaves 55 it must go to neighbor 44.
If operating correctly, the robot will always follow forced moves away from a node, and if reaching a node that does not have a forced move,the robot stops. Unfortunately,the robot is a bit buggy,and it might violate those rules and move to a randomly chosen neighbor of a node (whether or not there had been a designated forced move from that node). However, such a bug will occur at most once (and might never happen).
Alice is having trouble debugging the robot, and would like your help to determine what are the possible nodes where the robot could stop and not move again.
We consider two sample graphs, as given in Figures G.1 and G.2. In these figures, a red arrow indicate an edge corresponding to a forced move, while black arrows indicate edges to other neighbors. The circle around a node is red if it is a possible stopping node.
In the first example, the robot will cycle forever through nodes 1, 51,5, and 44 if it does not make a buggy move. A bug could cause it to jump from 11 to 22, but that would be the only buggy move, and so it would never move on from there. It might also jump from 55 to 66 and then have a forced move to end at 77.
In the second example, there are no forced moves, so the robot would stay at 11 without any buggy moves. It might also make a buggy move from 11 to either 22 or 33, after which it would stop.
Input
The first line contains two integers nn and mm, designating the number of nodes and number of edges such that 1 \le n \le 10^3, 0 \le m \le 10^41≤n≤103,0≤m≤104. The next mm lines will each have two integers aa and bb, 1 \le \lvert a \rvert ,b \le n1≤∣a∣,b≤n and \lvert a \rvert \ne b∣a∣=b. If a \gt 0a>0, there is a directed edge between nodes aa and bb that is not forced. If a \lt 0a<0, then there is a forced directed edge from -a−a to bb. There will be at most 900900 such forced moves. No two directed edges will be the same. No two starting nodes for forced moves will be the same.
Output
Display the number of nodes at which the robot might come to a rest.
样例输入1复制
7 9 1 2 2 3 -1 5 2 6 5 1 -4 1 5 6 -6 7 -5 4
样例输出1复制
2
样例输入2复制
3 2 1 2 1 3
样例输出2复制
3
题意:
有n个结点,m条边的有向图,其中存在一些武力边(用红色标记)
在正常条件下,机器人只能走武力边,如果这个结点没有武力边,就会停止行动;
现在出现了 bug,但是 bug最多只能出现一次
在有 bug的情况下,机器人可以随意走与之相连的边,但是用完 bug之后就不能再次使用,只能走武力边,如果没有武力边,就会停止
求最终停止的结点个数(要求是互不相同的)
思路:
可以搜索来做
需要注意的是:
(1) 为了判断环的问题,需要用到标记数组
(2) 在计数的时候,不能根据标记数组来加,因为在递归的时候,该点已经在上一次被标为了1(△处)
用flag 标记有没有用过bug
可以分情况讨论:
(1) 该点没有边肯定会停止
(2) 在flag = 1的前提下(还没有出现bug)
①:如果没有武力边就会停止(因为可能机器人并没出现bug)
②:如果存在武力边,继续走武力边,同时 flag = 1
③:如果此时出现了bug,那么就会走普通边,flag = 0
(3) 在flag = 0的前提下(已经出现了bug)
④:如果没有武力边就会停止(即使有普通边可是也没办法走)
⑤:继续走普通边
CODE:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <set>
#include <map>
#define memset(a,n) memset(a,n,sizeof(a))
#define INF 0x3f3f3f3f
using namespace std;
typedef long long LL;
const int MAXX = 1e3+10;
vector<vector<int> > vec(MAXX);
vector<vector<int> > vecf(MAXX);
int ans;
int num[MAXX];
int vis[MAXX];
void DFS(int x,int flag)
{
if(vec[x].size() == 0 && vecf[x].size() == 0){ // (1)
if(num[x] == 0) // △
ans++; // 上一次递归已经将vis赋为1,如果这里使用 if(vis[x] == 0) 的话,是不会满足条件的,所以新开一个标记数组 num,用来判断是否第一次在这个地方停止
num[x] = 1;
return ;
}
if(flag == 0 && vecf[x].size() == 0){ // ④
if(num[x] == 0)
ans++;
num[x] = 1;
return ;
}
if(flag == 0){
for(int i=0; i<vecf[x].size(); i++){ // ⑤
if(vis[vecf[x][i]] == 1)
return ;
vis[vecf[x][i]] = 1; // △
DFS(vecf[x][i],0);
vis[vecf[x][i]] = 0; // 记得重新赋值为0,下一次可能会通过其他的路径到达该点
}
} else {
for(int i=0; i<vec[x].size(); i++){ // ③
if(vis[vec[x][i]] == 1)
return ;
vis[vec[x][i]] = 1;
DFS(vec[x][i],0);
vis[vec[x][i]] = 0;
}
if(vecf[x].size() == 0){ // ①
if(num[x] == 0)
ans++;
num[x] = 1;
}
else {
for(int i=0; i<vecf[x].size(); i++){ // ②
if(vis[vecf[x][i]] == 1)
return ;
vis[vecf[x][i]] = 1;
DFS(vecf[x][i],1);
vis[vecf[x][i]] = 0;
}
}
}
}
int main()
{
int n,m,a,b;
cin >> n >> m;
for(int i=0; i<m; i++){
cin >> a >> b;
if(a > 0)
vec[a].push_back(b);
else
vecf[-a].push_back(b);
}
memset(vis,0);
memset(num,0);
//vis[1] = 1;
DFS(1,1);
cout << ans << endl;
}