Alien Security ZOJ - 1085(最短路SPFA+dfs)

在一个顶级政府研究设施中,为了保护被捕获的外星生命体,需要制定一套安全措施,确保只有特定级别的人员能够接近。本文介绍了一种算法,用于确定放置武装守卫的最佳位置,以最小化对无意访问外星区域的访客的干扰。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

                                           Alien Security

 

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 �C 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 �C 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.

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.

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.


This problem contains multiple test cases!

The first line of a multiple input is an integer N, then a blank line followed by N input blocks. Each input block is in the format indicated in the problem description. There is a blank line between input blocks.

The output format consists of N output blocks. There is a blank line between output blocks.

 


SAMPLE INPUT

This input sequence specifies the map shown above.

1

9 4
0 2
2 3
3 4
5 3
5 4
3 6
6 5
6 7
6 8
4 7
0 1
1 7
7 0


SAMPLE OUTPUT

Put guards in room 3. 

题目链接 我走~~~

首先来分析一下题意:乱78糟的一大堆,找了半天没抓到重点,头秃。。。

具体讲的是:有一个房间放着一个外星人,然后呢,不能让他们随便进,因而设立关卡,要求这关卡

(1)离ET最近

(2)且仅能通过该房间进入。

思路:我们可以通过最短路找寻该房间到其他房间的单源最短路径(因为图是单向的,因而方向建图)。然后用dfs找寻离ET最近且必经的点。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;

const int maxn = 1100;
const int INF = 0x3f3f3f3f;
int n, a, b, d[maxn];
bool v[maxn][maxn], used[maxn];

void spfa()
{
    queue <int> que;
    que.push(b);
    d[b] = 0;
    used[b] = true;

    while(!que.empty())
    {
        int x = que.front();
        que.pop();
        used[x] = false;

        for(int i = 0; i < a; i++)
        {
            if(v[i][x] && d[x] + 1 < d[i])
            {
                d[i] = d[x] + 1;
                if(used[i] == false)
                {
                    que.push(i);
                    used[i] = true;
                }
            }
        }
    }
}

bool dfs(int s)
{
    if(s == b)
        return 1;
    used[s] = 1;
    for(int i = 0; i< a; i++)
    {
        if(!used[i] && v[s][i]) // 倒搜寻没搜过的点,看有没有其他点可到达b
        {
            if(dfs(i))
                return 1;
        }
    }
    return 0;
}
int main()
{
    scanf("%d", &n);

    while(n--)
    {
        
        scanf("%d%d", &a, &b);
        char ch[10];

        for(int i = 0; i <= 110; i++)
        {
            for(int j = 0; j <= 110; j++)
            {
                v[i][j] = false;d[i] = INF;
                used[i] = false;
            }
        }

        getchar();

        while(gets(ch))
        {
            int c,d;
            if(strcmp(ch, "") == 0)
                break;
            sscanf(ch, "%d%d", &c, &d);
            v[c][d] = true; // 有单向路径的点
        }
        
        spfa();
        
        int dt = d[0], room = 0;

        for(int i = 1; i < a; i++)
        {
            if(i == b) continue;

            memset(used, 0, sizeof(used));
            used[i] = 1;

            if(!dfs(0) && d[i] < dt)
            {
                dt = d[i];
                room = i;
            }
        }
        printf("Put guards in room %d.\n",room);

        if(n != 0)
            printf("\n");
            
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值