• POJ 1275 Cashier Employment(差分约束)


    http://poj.org/problem?id=1275

    题意 : 一家24小时营业的超市,要雇出纳员,需要求出超市每天不同时段需要的出纳员数,午夜只需一小批,下午需要多些,希望雇最少的人,给出每小时需要的出纳员的最少数量,R(0),R(1),...,R(23)。R(0)表示从午夜到凌晨1:00所需要出纳员的最少数目;R(1)表示凌晨1:00到2:00之间需要的;以此类推。这些数据每一天都是相同的。有N人申请这工作,申请者 i ,从一个特定的时刻开始连续工作恰好8小时。定义ti(0<=ti<=23)为上面提到的开始时刻,也就是说,如果第i个申请者被录用,他)将从 ti 时刻开始连续工作8小时。

    思路 :差分约束,挺难的,看了好多人的题解,才稍微懂一些了,http://972169909-qq-com.iteye.com/blog/1185527,这个神写的不错,,,还有黑书上也有解释

    其实说的有点那啥,我一开始也还是没怎么看懂

    #include <iostream>
    #include <stdio.h>
    #include <string.h>
    #include <queue>
    
    using namespace std;
    
    const int INF = 9999999 ;
    struct node
    {
        int u,v,w ;
        int next ;
    } map[250] ;
    bool flag[25] ;
    int cnt,pre[25],cntt[25],dist[25] ;
    int r[25],t[26] ;
    
    void addedge(int u,int v,int w)
    {
        map[cnt].v = v ;
        map[cnt].w = w ;
        map[cnt].next = pre[u] ;
        pre[u] = cnt++ ;
    }
    
    void Init()
    {
        cnt = 0 ;
        memset(pre,-1,sizeof(pre)) ;
        memset(cntt,0,sizeof(cntt)) ;
        memset(flag,false,sizeof(flag)) ;
    }
    
    bool spfa(int start)
    {
        queue<int >Q ;
        for(int i = 0 ; i < 25 ; i++)
            dist[i] = -INF ;
        dist[start] = 0 ;
        Q.push(start) ;
        flag[start] = true ;
        while(!Q.empty())
        {
            int u = Q.front() ;
            Q.pop() ;
            if(++cntt[u] > 24)
                return false ;
            flag[u] = false ;
            for(int i = pre[u] ; i + 1 ; i = map[i].next)
            {
                int v = map[i].v ,w = map[i].w;
                if(dist[v] < dist[u] + w)
                {
                    dist[v] = dist[u] + w ;
                    if(!flag[v])
                    {
                        flag[v] = true ;
                        Q.push(v) ;
                    }
                }
            }
        }
        return true ;
    }
    int main()
    {
        int T ;
        scanf("%d",&T) ;
        while(T--)
        {
            for(int i = 1 ; i <= 24 ; i++)
                scanf("%d",&r[i]) ;
            int N ,s;
            scanf("%d",&N) ;
            memset(t,0,sizeof(t)) ;
            for(int i = 0 ; i < N ; i++)
            {
                scanf("%d",&s) ;
                t[s + 1]++ ;
            }
            int low = 0 ,high = N ;
            bool flagg = false ;
            while(low < high)
            {
                Init() ;
                int mid = (low+high)>>1 ;
                for(int i = 1 ; i <= 24 ; i++)
                {
                    addedge(i-1,i,0) ;
                    addedge(i,i-1,-t[i]) ;
                }
                for(int i = 8 ; i <= 24 ; i++)
                    addedge(i-8,i,r[i]) ;
                for(int i = 1 ; i <= 7 ; i++)
                    addedge(i+16,i,r[i]-mid) ;
                addedge(0,24,mid) ;
                if(spfa(0))
                {
                    high = mid ;
                    flagg = true ;
                }
                else low = mid+1 ;
            }
            if(flagg)
                printf("%d
    ",high) ;
            else printf("No Solution
    ") ;
        }
        return 0;
    }
    View Code
  • 相关阅读:
    win10家庭版转专业版并激活
    关于vcruntime140D.dll丢失问题
    phpMyAdmin使用教程
    在wamp中直接进入项目
    sublime Text3的使用
    wamp的安装配置
    PHP Web开发入门流程
    PHP与MySQL的亲密接触
    flex 布局 实现电商页面商品展示floor
    html css+div+jquery实现图片轮播
  • 原文地址:https://www.cnblogs.com/luyingfeng/p/3542425.html
Copyright © 2020-2023  润新知