• POJ 3084 Panic Room


    题意:有m个房间,你需要保护第n个房间使得其不被攻入。房间与房间之间会有门,门上有机关,因此当门关上时,只能从一边进入另外一边而不能从相反方向进入。现在告诉你这n个房间以及门的分布情况,以及开始的时候哪些房间里有贼,问至少关掉几个门使得房间n不被攻入。

    感觉这个题目蛮有意思的。比较容易想到最小割。如果从房间a到房间b有一个门,如果这个门关上了,且门上的机关使得贼只能从a进入b而不能让其从b进入a,那么这里对应两条边(a,b,inf),(b,a,1),如果房间i里面有贼,对应边(S,i,inf),而需要保护的那个房间n就会汇点T。然后求一遍最大流。如果maxflow>=inf就说明不存在合法方案了,否则maxflow就是答案。而流的意思就是要关掉多少扇门了。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #define maxn 25
     5 #define maxm 1000000
     6 #define INF 1<<20
     7 using namespace std;
     8 int v[maxm],next[maxm],w[maxm];
     9 int first[maxn],q[maxn],d[maxn],work[maxn];
    10 int e,S,T;
    11 
    12 void init(){
    13     e = 0;
    14     memset(first,-1,sizeof(first));
    15 }
    16 
    17 void add_edge(int a,int b,int c){
    18     v[e] = b;next[e] = first[a];w[e] = c;first[a] = e++;
    19 }
    20 
    21 int bfs(){
    22     int rear = 0;
    23     memset(d,-1,sizeof(d));
    24     d[S] = 0;q[rear++] = S;
    25     for(int i = 0;i < rear;i++){
    26         for(int j = first[q[i]];j != -1;j = next[j])
    27             if(w[j] && d[v[j]] == -1){
    28                 d[v[j]] = d[q[i]] + 1;
    29                 q[rear++] = v[j];
    30                 if(v[j] == T)   return 1;
    31             }
    32     }
    33     return 0;
    34 }
    35 
    36 int dfs(int cur,int a){
    37     if(cur == T)    return a;
    38     for(int &i = work[cur];i != -1;i = next[i]){
    39         if(w[i] && d[v[i]] == d[cur] + 1)
    40             if(int t = dfs(v[i],min(a,w[i]))){
    41                 w[i] -= t;w[i^1] += t;
    42                 return t;
    43             }
    44     }
    45     return 0;
    46 }
    47 
    48 int dinic(){
    49     int ans = 0;
    50     while(bfs()){
    51         memcpy(work,first,sizeof(first));
    52         ans += dfs(S,INF);
    53     }
    54     return ans;
    55 }
    56 
    57 int main()
    58 {
    59     int kase,n;
    60     char str[10];
    61     scanf("%d",&kase);
    62     while(kase--){
    63         init();
    64         scanf("%d%d",&n,&T);
    65         S = n+1;
    66         for(int i = 0;i < n;i++){
    67             int c,num;
    68             scanf("%s %d",str,&c);
    69             if(str[0] == 'I'){
    70                 add_edge(S,i,INF);
    71                 add_edge(i,S,0);
    72             }
    73             while(c--){
    74                 scanf("%d",&num);
    75                 add_edge(i,num,INF);
    76                 add_edge(num,i,1);
    77             }
    78         }
    79         int ans = dinic();
    80         if(ans >= INF)  printf("PANIC ROOM BREACH
    ");
    81         else    printf("%d
    ",ans);
    82     }
    83     return 0;
    84 }
    View Code
  • 相关阅读:
    socket通信原理
    socket通信基础内容
    内核中断过程
    爬虫基础模块
    关于多个运算符的问题
    前戏
    js扩展
    加密
    django之form
    Django
  • 原文地址:https://www.cnblogs.com/zhexipinnong/p/3416869.html
Copyright © 2020-2023  润新知