Peng Lv

毋意,毋必,毋固,毋我。 言必行,行必果。

导航

POJ 3084 Panic Room

这个题的题意不怎么好理解,关键是英语句子有点别扭。。题意:给你几个屋子,其中有些是恐怖者的屋子,有一个是需要保护的屋子,题目要求是不让恐怖者来到受保护的屋子。刚开始所有的门是打开的,让你求出最少需要关闭多少门,才能保证恐怖者不会到达目的地。
I 2 1 2 表示这个屋子是恐怖者,可以直接进入1房和2房。剩下的就是建图了,加一个源点,连边权为inf到所有的恐怖者的屋子,如果i->j,则从i连一条边权为INF到j,从j连一条边权为1的到i,可以证明,依靠最小割定理,求出最大流便是结果,如果最大流>=inf,则无解。
在求最大流时,因为ISAP()求cur_flow时,也用到了inf,结果造成了边权的冲突,错了很长时间.........,改成inf+1就OK了

 

code
#include <iostream>
#include 
<cstdio>
#include 
<algorithm>
#include 
<memory.h>
using namespace std;
#define MAXN 50
#define MAXE 10000
#define INF 0x3fffffff
int ne,nv,s,t,index,net[MAXN];
struct Edge{
    
int next,pair;
    
int v,flow,cap;
}edge[MAXE];
void add(const int& u,const int& v,const int& val,const int& val2)
{
    edge[index].next 
= net[u];
    net[u] 
= index;
    edge[index].v 
= v;
    edge[index].cap 
= val;
    edge[index].flow 
= 0;
    edge[index].pair 
= index + 1;
    
++index;
    edge[index].next 
= net[v];
    net[v] 
= index;
    edge[index].v 
= u;
    edge[index].cap 
= val2;
    edge[index].flow 
= 0;
    edge[index].pair 
= index - 1;
    
++index;
}
int ISAP()
{
    
int numb[MAXN],dist[MAXN],curedge[MAXN],pre[MAXN];
    
int cur_flow,max_flow,u,tmp,neck,i;
    memset(dist,
0,sizeof(dist));
    memset(numb,
0,sizeof(numb));
    
for(i = 1 ; i <= nv ; ++i)
        curedge[i] 
= net[i];
    numb[nv] 
= nv;
    max_flow 
= 0;
    u 
= s;
    
while(dist[s] < nv){
        
if(u == t){
            cur_flow 
= INF+1;
            
for(i = s; i != t;i = edge[curedge[i]].v) 
                
if(cur_flow > edge[curedge[i]].cap){
                    neck 
= i;
                    cur_flow 
= edge[curedge[i]].cap;
                }
            
for(i = s; i != t; i = edge[curedge[i]].v)
            {
                tmp 
= curedge[i];
                edge[tmp].cap 
-= cur_flow;
                edge[tmp].flow 
+= cur_flow;
                tmp 
= edge[tmp].pair;
                edge[tmp].cap 
+= cur_flow;
                edge[tmp].flow 
-= cur_flow;
            }
            max_flow 
+= cur_flow;
            u 
= neck;
        }
        
for(i = curedge[u]; i != -1; i = edge[i].next)
            
if(edge[i].cap > 0 && dist[u] == dist[edge[i].v]+1)
                
break;
        
if(i != -1){
            curedge[u] 
= i;
            pre[edge[i].v] 
= u;
            u 
= edge[i].v;
        }
else{
            
if(0 == --numb[dist[u]]) break;
            curedge[u] 
= net[u];
            
for(tmp = nv,i = net[u]; i != -1; i = edge[i].next)
                
if(edge[i].cap > 0)
                    tmp 
= tmp<dist[edge[i].v]?tmp:dist[edge[i].v];
            dist[u] 
= tmp + 1;
            
++numb[dist[u]];
            
if(u != s) u = pre[u];
        }
    }
    
return max_flow;
}

int main()
{
    
int i,j,tt,k,time,a,b,val,tmp,n;
    
char str[10];
    scanf(
"%d",&time);
    
while(time--)
    {
        index 
= 0;
        memset(net,
-1,sizeof(net));
        scanf(
"%d%d",&n,&t);
        s 
= n + 1;
        nv 
= s; ++t;
        
for(i = 1;i <= n; ++i)
        {
            scanf(
"%s %d",str,&k);
            
if(str[0== 'I')
                add(s,i,INF,
0);
            
for(j = 1;j <= k; ++j)
            {
                scanf(
"%d",&a);
                add(i,a
+1,INF,1);
            }
        }
        tmp 
= ISAP();
        
if(tmp>=INF)
            printf(
"PANIC ROOM BREACH\n");
        
else
            printf(
"%d\n",tmp);
    }
    
return 0;
}

 

 

 

posted on 2010-02-03 16:03  Lvpengms  阅读(486)  评论(0编辑  收藏  举报