Description

You are the lead programmer for the Securitron 9042, the latest and greatest in home security software from Jellern Inc. (Motto: We secure your stuff so YOU can't even get to it). The software is designed to "secure" a room; it does this by determining the minimum number of locks it has to perform to prevent access to a given room from one or more other rooms. Each door connects two rooms and has a single control panel that will unlock it. This control panel is accessible from only one side of the door. So, for example, if the layout of a house looked like this:    with rooms numbered 0-6 and control panels marked with the letters "CP" (each next to the door it can unlock and in the room that it is accessible from), then one could say that the minimum number of locks to perform to secure room 2 from room 1 is two; one has to lock the door between room 2 and room 1 and the door between room 3 and room 1. Note that it is impossible to secure room 2 from room 3, since one would always be able to use the control panel in room 3 that unlocks the door between room 3 and room 2. 

Input

Input to this problem will begin with a line containing a single integer x indicating the number of datasets. Each data set consists of two components:
  1. Start line – a single line "m n" (1 <=m<= 20; 0 <=n<= 19) where m indicates the number of rooms in the house and n indicates the room to secure (the panic room).
  2. Room list – a series of m lines. Each line lists, for a single room, whether there is an intruder in that room ("I" for intruder, "NI" for no intruder), a count of doors c (0 <= c <= 20) that lead to other rooms and have a control panel in this room, and a list of rooms that those doors lead to. For example, if room 3 had no intruder, and doors to rooms 1 and 2, and each of those doors' control panels were accessible from room 3 (as is the case in the above layout), the line for room 3 would read "NI 2 1 2". The first line in the list represents room 0. The second line represents room 1, and so on until the last line, which represents room m - 1. On each line, the rooms are always listed in ascending order. It is possible for rooms to be connected by multiple doors and for there to be more than one intruder!

Output

For each dataset, output the fewest number of locks to perform to secure the panic room from all the intruders. If it is impossible to secure the panic room from all the intruders, output "PANIC ROOM BREACH". Assume that all doors start out unlocked and there will not be an intruder in the panic room.

题目大意:有n个房间,若干扇门,门是单向的,只能从一边上锁(如一道门连接a→b,任何时刻都能从a走到b,但上了锁之后就不能从b走到a了)。现在有些坏蛋入侵了一些房间,你不想让他们来到你的房间,问最少要锁上多少扇门,若全锁上都木有用……就……

思路:新建一个源点S,从S到坏蛋们入侵的房间连一条容量为无穷大的边,对每扇门a→b,连一条边a→b容量为无穷大,连b→a容量为1。若最大流≥无穷大(我是增广到一条容量为无穷大的路径直接退出),则无解(死定啦死定啦),否则最大流为答案。实则为求最小割,好像不需要解释了挺好理解的……

 #include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAXN = ;
const int MAXE = ;
const int INF = 0x3fff3fff; struct SAP {
int head[MAXN], dis[MAXN], pre[MAXN], cur[MAXN], gap[MAXN];
int to[MAXE], next[MAXE], flow[MAXE];
int n, st, ed, ecnt; void init() {
memset(head, , sizeof(head));
ecnt = ;
} void add_edge(int u, int v, int c) {
to[ecnt] = v; flow[ecnt] = c; next[ecnt] = head[u]; head[u] = ecnt++;
to[ecnt] = u; flow[ecnt] = ; next[ecnt] = head[v]; head[v] = ecnt++;
//printf("%d->%d flow = %d\n", u, v, c);
} void bfs() {
memset(dis, 0x3f, sizeof(dis));
queue<int> que; que.push(ed);
dis[ed] = ;
while(!que.empty()) {
int u = que.front(); que.pop();
++gap[dis[u]];
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p ^ ] && dis[v] > n) {
dis[v] = dis[u] + ;
que.push(v);
}
}
}
} int Max_flow(int ss, int tt, int nn) {
st = ss; ed = tt; n = nn;
int ans = , minFlow = INF, u;
for(int i = ; i <= n; ++i) {
cur[i] = head[i];
gap[i] = ;
}
u = pre[st] = st;
bfs();
while(dis[st] < n) {
bool flag = false;
for(int &p = cur[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && dis[u] == dis[v] + ) {
flag = true;
minFlow = min(minFlow, flow[p]);
pre[v] = u;
u = v;
if(u == ed) {
if(minFlow == INF) return INF;//no ans
ans += minFlow;
while(u != st) {
u = pre[u];
flow[cur[u]] -= minFlow;
flow[cur[u] ^ ] += minFlow;
}
minFlow = INF;
}
break;
}
}
if(flag) continue;
int minDis = n - ;
for(int p = head[u]; p; p = next[p]) {
int &v = to[p];
if(flow[p] && minDis > dis[v]) {
minDis = dis[v];
cur[u] = p;
}
}
if(--gap[dis[u]] == ) break;
gap[dis[u] = minDis + ]++;
u = pre[u];
}
return ans;
}
} G; char s[];
int n, ss, tt, T, c, x; int main() {
scanf("%d", &T);
while(T--) {
scanf("%d%d", &n, &tt);
ss = n;
G.init();
for(int i = ; i < n; ++i) {
scanf("%s%d", s, &c);
while(c--) {
scanf("%d", &x);
G.add_edge(i, x, INF);
G.add_edge(x, i, );
}
if(s[] == 'I') G.add_edge(ss, i, INF);
}
int ans = G.Max_flow(ss, tt, ss);
if(ans == INF) puts("PANIC ROOM BREACH");
else printf("%d\n", ans);
}
}

POJ 3084 Panic Room(最大流最小割)的更多相关文章

  1. POJ 3084 Panic Room (最小割建模)

    [题意]理解了半天--大意就是,有一些房间,初始时某些房间之间有一些门,并且这些门是打开的,也就是可以来回走动的,但是这些门是确切属于某个房间的,也就是说如果要锁门,则只有在那个房间里才能锁. 现在一 ...

  2. POJ 3308 Paratroopers(最大流最小割の最小点权覆盖)

    Description It is year 2500 A.D. and there is a terrible war between the forces of the Earth and the ...

  3. POJ 2987 Firing(最大流最小割の最大权闭合图)

    Description You’ve finally got mad at “the world’s most stupid” employees of yours and decided to do ...

  4. POJ 1815 Friendship(最大流最小割の字典序割点集)

    Description In modern society, each person has his own friends. Since all the people are very busy, ...

  5. HDU 1569 方格取数(2)(最大流最小割の最大权独立集)

    Description 给你一个m*n的格子的棋盘,每个格子里面有一个非负数. 从中取出若干个数,使得任意的两个数所在的格子没有公共边,就是说所取数所在的2个格子不能相邻,并且取出的数的和最大.   ...

  6. hiho 第116周,最大流最小割定理,求最小割集S,T

    小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? 小Ho:我记得!网络流就是给定了一张图G=(V,E),以及源点s和汇点t.每一条边e(u,v)具有容量c ...

  7. hihocoder 网络流二·最大流最小割定理

    网络流二·最大流最小割定理 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 小Hi:在上一周的Hiho一下中我们初步讲解了网络流的概念以及常规解法,小Ho你还记得内容么? ...

  8. [HihoCoder1378]网络流二·最大流最小割定理

    思路: 根据最大流最小割定理可得最大流与最小割相等,所以可以先跑一遍EdmondsKarp算法.接下来要求的是经过最小割切割后的图中$S$所属的点集.本来的思路是用并查集处理所有前向边构成的残量网络, ...

  9. FZU 1844 Earthquake Damage(最大流最小割)

    Problem Description Open Source Tools help earthquake researchers stay a step ahead. Many geological ...

随机推荐

  1. 通过ES6写法去对Redux部分源码解读

    在Redux源码中主要有四个文件createStore,applyMiddleware,bindActionCreators,combineRedures createStore.js export ...

  2. Ubuntu更换国内源

    打开终端,输入:sudo gedit /etc/apt/sources.list 在文件最底部输入以下内容: deb http://mirrors.ustc.edu.cn/ubuntu/ xenial ...

  3. What is a schema in a MySQL database?

    摘自:https://www.quora.com/What-is-a-schema-in-a-MySQL-database What is schema? In MySQL, physically, ...

  4. MySQL正则表达式的问题

    原本以为 正则表达式里面的特殊\d匹配数字放到sql语句里面也是适用的,没想到一直不匹配.但是放到编程语言java或者js里面又匹配.看了一下原来sql对正则的支持没有那么全面.一定要用[0-9]代表 ...

  5. 4 二维数组中的查找 JavaScript

    题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...

  6. vue组件间传值详解

    1.父传子----传值要点: <1> 在组件注册的时候必须要使用 return 去返回 data对象;

  7. 使用什么进行app开发

    HTML5+plus, Hbuilder HTML5+plus介绍 HTML5 Plus移动App,简称5+App,是一种基于HTML.JS.CSS编写的运行于手机端的App,这种App可以通过扩展的 ...

  8. BINARYSEARCH有り無しのパフォーマンスの違い

    BINARY SEARCHを使用したパフォーマンス検証を行ってみた.この例では.BKPFが約1万件.BSEGが約3万件になるよう調整している.また.SQLの実行に係る時間は無視する事にする. サンプル ...

  9. JavaWeb——库存管理系统(2).java部分---18.12.13

    DBUtil.java package com.hjf.util; import java.sql.Connection;import java.sql.DriverManager;import ja ...

  10. sql 删除表字段中所有的空格

    源地址:http://bbs.csdn.net/topics/30322040 Sample表中有一个Name字段,目前当中有很多记录含有空格,如:“ 张 学 友 ”,如何用SQL语句将这些空格删掉, ...