• 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;
    }
  • 相关阅读:
    Java线程
    腾讯2012.9.23校园招聘笔试题
    腾讯2011.10.15校园招聘笔试题
    腾讯2013年实习生笔试题目
    腾讯2012.4.25实习生招聘笔试题(2)
    腾讯2012.4.25实习生招聘笔试题
    优酷土豆2012.9.12校园招聘笔试题
    谷歌面试题:在半径为1的圆中随机选取一点
    Reservoir Sampling
    微软面试15道
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662732.html
Copyright © 2020-2023  润新知