Alien Security

来源:互联网 发布:绿色傲剑金蛇数据 编辑:程序博客网 时间:2024/05/29 23:48

Description

You are in charge of security at a top-secret government research facility. Recently your government has captured a live extra-terrestrial (ET) life form, and is hosting an open day for fellow researchers. Of course, not all the guests can be trusted, so they are assigned different security clearance levels. Only guests with a level 5 rating will be allowed into the lab where the extra-terrestrial is being held; other than that, everyone is free to roam throughout the rest of the facility. Each room in the facility is connected via one-way airlocks, so that you can pass through the door in only one direction. 

To protect your precious ET you will put in place enhanced security measures (in the form of armed guards) on the route leading to the room containing the ET, but not in the room itself ?the guards do not have sufficient clearance to enter the room containing the ET. 

The guards will check the identity and the security rating of all guests trying to pass through the room in which they are stationed, so you would like to place the guards where they will cause the minimum amount of irritation to the guests who have no intention of visiting the ET. The room where the guards must be placed thus satisfies the following two conditions: 

1. In order to get to the room containing the ET, the guests must pass through the room containing the guards; 

2. There is no other room with this property that is closer to the room containing the ET ?remember, the guards cannot be placed in the room containing the ET itself. 

The diagram below illustrates one possible map of your facility: 

Note that placing the guards in room 2 would satisfy the first condition, but room 3 is closer to the ET, so the guards must be placed in room 3.

Input

All guests enter through room 0, the entrance to your facility. Your program accepts a sequence of lines containing integers. The first line consists of two integers: the number of rooms, and the room in which the ET is being held (out of his own free will, of course). 

The rest of the input is a sequence of lines consisting of only two integers, specifying where the airlock-doors are located. The first number on these lines specifies the source room, and the second the destination room. Remember: you can pass only from the source room to the destination room.

Output

The output of your program consists only of a single line: 

Put guards in room N. 

where N is the room you've decided to place the guards.

Sample Input

9 40 22 33 45 35 43 66 56 76 84 70 11 77 0

Sample Output

Put guards in room 3.

这道题目篇幅略长,如果没能注意到其中的一些细节,往往会出错,而且这道题作为我spfa的入门题自然要好好分析一下

首先,解这道题需要用到spfa和dfs(当然这道题也存在很多解法),我使用邻接表作为存储对象,这道题目的数据范围不明确,应该在100以内,其次这道题目读入格式非常特殊

while(gets(str)){if(strcmp(str,"")==0)break;int a,b;sscanf(str,"%d %d",&a,&b);an[a].push_back(b);rean[b].push_back(a);}

题目没有告知数据的数目,但是观察样例,在数据输入结束时会有额外的一行,起先我认为那一行是由空格构成的,但是那就是个空行,把数据读入成字符串后,还需要sscanf把字符串再重新读成数字(具体使用请看我的基础知识(1)),解释一下为什么要用两个vector的二维数组,这道题中所有的边都是单向边,而又要求到外星人的那间房间距离尽量短,这就需要把那间房间看做是起点并把所有的单向边翻转,使原本到达那间房间的,变为被那间房间到达的,这样便于最短距离的计算

void spfa(int s){fill(dis,dis+n+1,inf);queue<int> q;q.push(s);dis[s]=0;while(!q.empty()){int Q=q.front();q.pop();for(int i=0;i<rean[Q].size();i++){int des=rean[Q][i];if(dis[des]>dis[Q]+1){dis[des]=dis[Q]+1;q.push(des);}}}}
这个并不是完整的spfa,因为这道题并不需要对负环的判断

int min=dis[0];          int mini=0;              for(int i=0;i<=n;i++){if(i==room)continue;memset(book,false,sizeof(book));book[i]=true;book[0]=true;if(dis[i]<min&&!dfs(0)){min=dis[i];mini=i;}}
这是代码的最后一部分,即使用dfs判断某个点删去后能否使得0号房间不能到达外星人所在的房间,这里的初始化需要注意一下,如果没有可能会影响结果的得出
#include<stdio.h>#include<string.h>#include<queue>#include<vector>#include<algorithm>#define maxn 105#define inf 0x3f3f3f3fusing namespace std;bool cmp(int a,int b){return a<b;}vector<int> an[maxn],rean[maxn];void spfa(int s);bool dfs(int s);int n,room,dis[maxn],num[maxn];bool inq[maxn],book[maxn];int main(){int t,flag;scanf("%d",&t);flag=0;while(t--){if(flag)printf("\n");flag=1;char str[100]={0};scanf("%d%d",&n,&room);getchar();for(int i=0;i<=n;i++){an[i].clear();rean[i].clear();}while(gets(str)){if(strcmp(str,"")==0)break;int a,b;sscanf(str,"%d %d",&a,&b);an[a].push_back(b);rean[b].push_back(a);}spfa(room);int min=dis[0];          int mini=0;              for(int i=0;i<=n;i++){if(i==room)continue;memset(book,false,sizeof(book));book[i]=true;book[0]=true;if(dis[i]<min&&!dfs(0)){min=dis[i];mini=i;}}printf("Put guards in room %d.\n",mini);}return 0;} void spfa(int s){fill(dis,dis+n+1,inf);queue<int> q;q.push(s);dis[s]=0;while(!q.empty()){int Q=q.front();q.pop();for(int i=0;i<rean[Q].size();i++){int des=rean[Q][i];if(dis[des]>dis[Q]+1){dis[des]=dis[Q]+1;q.push(des);}}}}bool dfs(int s){if(s==room)return true;for(int i=0;i<an[s].size();i++){if(book[an[s][i]]==false){book[an[s][i]]=true;if(dfs(an[s][i]))return true;}}return false;}