zoukankan      html  css  js  c++  java
  • POJ 1698 Alice's Chance

    /* 一个演员很想参加film,但是一天只能参加一项,且每项必须在规定的几个星期内参加规定的天数,求演员是否能全部完成所有的film档期。 可以考虑用网络流做,加源汇点,如果film_i 和week_i_day_j天有联系,那么就连一条INF边,源点到film_i连一条day_i边,各个星期的天数到汇点连一条1边,求最大流是否和总天数相等。最大流用isap就可以了,非常快。 */

    #include <iostream>
    #include 
    <cstdio>
    #include 
    <algorithm>
    #include 
    <memory.h>
    #include 
    <queue>
    using namespace std;

    #define INF 0x7ffffff
    #define MAXN 500
    #define MAXE 20000

    struct Edge{
        
    int next,pair;
        
    int v,cap,flow;
    }edge[MAXE];
    int net[MAXN];
    int nv,ne,s,t,index,max_week,sum;
    void init()
    {
        index 
    = 0;
        memset(net,
    -1,sizeof(net));
        s 
    = 0// start position
        max_week = -1;
        sum 
    = 0;
    }
    void add_edge(const int& u,const int& v,const int& val)
    {
        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 
    = 0;
        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,k,h,time,ans,n,work[7],day,week;
        scanf(
    "%d",&time);
        
    while(time--)
        {
            init();
            scanf(
    "%d",&n);
            
    for(i = 1; i <= n; ++i)
            {
                
    for(j = 0;j < 7++j)
                    scanf(
    "%d",&work[j]);
                scanf(
    "%d%d",&day,&week);
                add_edge(s,i,day);
                
    for(j = 0;j < week; ++j)
                    
    for(k = 0;k < 7++k)
                        
    if(work[k]) // can do 
                            add_edge(i,n+j*7+k+1,INF);
                max_week 
    = max_week>week?max_week:week;
                sum 
    += day;
            }
            t 
    = n+max_week*7+1;
            nv 
    = t + 1;
            
    for(i = 0;i < max_week; ++i )
                
    for(j = 1;j <= 7++j)
                    add_edge(n
    +i*7+j,t,1);
            ans 
    = ISAP();
            
    if(sum == ans)
                printf(
    "Yes\n");
            
    else
                printf(
    "No\n");
        }
        
    return 0;
    }

     

  • 相关阅读:
    行为树AI设计及BehaviorTree结构分析
    Android填坑—Error:Execution failed for task ':app:transformClassesWithDexForRelease'
    编程练习-字母异位词分组
    编程练习-判断是否为易混淆数
    编程练习-寻找最长回文串
    Android 8悬浮窗适配
    编程练习-字符串展开
    编程练习-只用0交换排序数组
    Android工程方法数超过64k,The number of method references in a .dex file cannot exceed 64K.
    Eclipse项目导入到Android Studio中
  • 原文地址:https://www.cnblogs.com/lvpengms/p/1662746.html
Copyright © 2011-2022 走看看