Faulty Robot

5094: Faulty Robot

时间限制: 1 Sec   内存限制: 128 MB
提交: 85   解决: 27
[ 提交][ 状态][ 讨论版][命题人: admin]

题目描述

As part of a CS course, Alice just finished programming her robot to explore a graph having n nodes, labeled 1, 2, . . . , n, and m directed edges. Initially the robot starts at node 1.
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.

输入

The first line contains two integers n and m, designating the number of nodes and number of edges such that 1 ≤ n ≤ 103, 0 ≤ m ≤ 104. The next m lines will each have two integers a and b, 1 ≤ |a|, b ≤ n and |a| ≠ b. If a > 0, there is a directed edge between nodes a and b that is not forced. If a < 0, then there is a forced directed edge from −a to b. There will be at most 900 such forced moves. No two directed edges will be the same. No two starting nodes for forced moves will be the same.

输出

Display the number of nodes at which the robot might come to a rest.

样例输入

7 9
1 2
2 3
-1 5
2 6
5 1
-4 1
5 6
-6 7
-5 4

样例输出

2

题意:有n个结点,n个结点之间有m条有向边,现在有一个机器人从1开始出发在没有bug的时候只能通过强迫边(输入时a为负数的边),有bug的时候可以选择其它边走,bug只能发生一次也可以一次都不发生。在这种情况下机器人可以在哪几个点永远的停下(该点没有强迫边通向其它点)。

分析:直接dfs就可以,n是10^3竟然没有超时。用spfa走最短路也可以,把强迫边权值初始化为0,其它边为1,最后找最短路小于等于1的即可。

#include<stdio.h>
#include <algorithm>
#include<iostream>
#include<string.h>
#include<vector>
#include<stdlib.h>
#include<math.h>
#include<queue>
#include<deque>
#include<ctype.h>
#include<map>
#include<set>
#include<stack>
#include<string>
#include<algorithm>
#define INF 0x3f3f3f3f
#define gcd(a,b) __gcd(a,b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define FAST_IO ios::sync_with_stdio(false)
const double PI = acos(-1.0);
const double eps = 1e-6;
const int MAX=1e5+10;
const int mod=1e9+7;
typedef long long ll;
using namespace std;

inline ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
inline ll qpow(ll a,ll b){ll r=1,t=a; while(b){if(b&1)r=(r*t)%mod;b>>=1;t=(t*t)%mod;}return r;}
inline ll inv1(ll b){return qpow(b,mod-2);}
inline ll exgcd(ll a,ll b,ll &x,ll &y){if(!b){x=1;y=0;return a;}ll r=exgcd(b,a%b,y,x);y-=(a/b)*x;return r;}
inline ll read(){ll x=0,f=1;char c=getchar();for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;for(;isdigit(c);c=getchar()) x=x*10+c-'0';return x*f;}

int mp[1005][1005];
int n,m,flag=0,ans=0,vis[1005][1005]={0};
int v[1005]={0};
int judge(int x)
{
    int i,p=0;
    for(i=1;i<=n;i++)
    {
        if(mp[x][i]==1)
            return 0;
    }
    return 1;
}
void dfs(int x)
{
    int i,j;
    
    if(!flag)
    {
        for(i=1;i<=n;i++)
        {
            if(mp[x][i]==1 && !vis[x][i])
            {
                vis[x][i]=1;
                dfs(i);
                vis[x][i]=0;
            }
            else if(mp[x][i]==0 && !vis[x][i])
            {
                flag=1;
                vis[x][i]=1;
                dfs(i);
                flag=0;
                vis[x][i]=0;
            }
        }
    }
    else
    {
        for(i=1;i<=n;i++)
        {
            if(mp[x][i]==1 && !vis[x][i])
            {
                vis[x][i]=1;
                dfs(i);
                vis[x][i]=0;
            }
        }
    }
    if(judge(x) && x!=1)//这个判断必须放在后面
    {
        if(!v[x])
        {
            ans++;
            v[x]=1;
            //printf("%d\n",x);
        }
        return;
    }
}
int main()
{
    int i,j;
    scanf("%d%d",&n,&m);
    memset(mp,-1,sizeof(mp));
    for(i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        if(a<0)
            mp[-a][b]=1;
        else
            mp[a][b]=0;
    }
    dfs(1);
    for(i=2;i<=n;i++)//考虑1没有与任何点通过强迫边相连的情况
    {
        if(mp[1][i]==1)
            break;
    }
    if(i>n)
        ans++;
    printf("%d\n",ans);
    return 0;
}


猜你喜欢

转载自blog.csdn.net/ToBeYours/article/details/80053765