mcpc2017 Faulty Robot

 

问题 G: Faulty Robot

时间限制: 1 Sec  内存限制: 128 MB
提交: 56  解决: 19
[提交][状态][讨论版][命题人: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个节点,m条有向边,当某个顶点的出边有红色边时,必须走红色边。不过机器人的程序有点bug,可能会发生变异,变异的次数最多1次,最少0次。对于出边为黑色的边,只有当发生变异的时候才能够通过(即当机器人发生变异时可以选择任意颜色的出边);求该图中最多有几个休息点(即当前顶点出边没有红色边或者没有出边);

其中该图没有重边,同一个顶点不会有两条红色出边。

【思路】dfs暴力遍历,在搜索的同时判断当前节点的所有出边,没有出边或者出边全为黑标记并+1,存在红边时,继续搜索,对于黑边,如果当前可以遍历,则搜索该黑边,否则不搜索。

【代码如下】

 

#include<bits/stdc++.h>
using namespace std;

const int N=1e6+5;
const int INF=0x3f3f3f3f;
int vis[1100],head[1100],cnt,n,m,ans,ok[1100];
struct Edge{
    int flag,next,v;
}edge[11000];

void add(int u, int v, int flag){
    edge[cnt].v = v;
    edge[cnt].next = head[u];
    edge[cnt].flag = flag;
    head[u] = cnt ++;
}

void dfs(int x, int cur){
    int fb=0,sum=0;
    for(int i = head[x]; ~i; i = edge[i].next){
        int v = edge[i].v, flag = edge[i].flag;
        sum ++;
       // printf("%d******%d\n",v,cur);
        if(flag && !vis[v]){
            vis[v] = 1;
            dfs(v,cur);
            vis[v] = 0;
        }
        else if(!flag){   //printf("%d*****%d\n",v,cur);
            //ans ++;
            //vis[v] = 1;
            if(cur) dfs(v,cur-1);
            fb ++;
        }
    }
    //printf("%d   %d   %d   %d\n",x,fb,sum,cur);
    if(sum == fb && !ok[x]) ans ++,ok[x]=1;//printf("%d******\n",x);
}

int main(){
    scanf("%d%d",&n,&m);
    memset(head,-1,sizeof(head));
    memset(ok,0,sizeof(ok));
    cnt = ans = 0;
    for(int i = 0; i < m; i ++){
        int u,v;
        scanf("%d%d",&u,&v);
        if(u<0) add(abs(u),v,1);
        else add(u,v,0);
    }
    memset(vis,0,sizeof(vis));
    vis[1] = 1;
    dfs(1,1);
    printf("%d\n",ans);
    return 0;
}
/*
6 8
1 2
-2 3
3 4
-3 6
-6 2
6 5
5 2
5 1

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

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值