连通分量!
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 5 has outgoing edges to neighbors 1, 4, and 6 but that Alice programs the robot so that if it leaves 5 it must go to neighbor 4.
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, 5, and 4 if it does not make a buggy move.
A bug could cause it to jump from 1 to 2, but that would be the only buggy move, and so it would never move on from there. It might also jump from 5 to 6 and then have a forced move to end at 7.
In the second example, there are no forced moves, so the robot would stay at 1 without any buggy moves. It might also make a buggy move from 1 to either 2 or 3, after which it would stop.
输入
输出
样例输入
7 9
1 2
2 3
-1 5
2 6
5 1
-4 1
5 6
-6 7
-5 4
样例输出
2
计算离主连通分量距离为1的连通分量条数,然后判断主连通分量是否有环,没有则加1。
AC代码:
#include <bits/stdc++.h>
using namespace std;
int ma[1005][1005],vis[1005],look[1005],cun[1005],see[1005];
int main()
{
int n,m,x,y,cnt=0,temp,sum=0;
vis[1]=1;
scanf("%d %d",&n,&m);
while(m--)
{
scanf("%d %d",&x,&y);
if(x<0)
{
see[-x]=y;
ma[-x][0]++;
ma[-x][ma[-x][0]]=-y;
}
else
{
ma[x][0]++;
ma[x][ma[x][0]]=y;
}
}
temp=1;
while(1)
{
int p=0;
int q=0;
int z=temp;
for(int i=1;i<=ma[z][0];i++)
{
if(ma[z][i]<0)
{
if(vis[-ma[temp][i]]==1)
{
q++;
break;
}
p++;
temp=-ma[temp][i];
vis[temp]=1;
}
else
{
look[ma[z][i]]=1;
}
}
if(q>0)
{
break;
}
if(p==0)
{
sum++;
break;
}
}
for(int i=0;i<=n;i++)
{
if(look[i]==1)
{
cun[cnt++]=i;
}
}
for(int i=0;i<=cnt-1;i++)
{
if(vis[cun[i]]==1)
{
continue;
}
temp=cun[i];
while(1)
{
if(see[temp]==0)
{
sum++;
vis[temp]=1;
break;
}
else
{
vis[temp]=1;
temp=see[temp];
if(vis[temp]==1)
{
break;
}
}
}
}
printf("%d\n",sum);
return 0;
}