zoukankan      html  css  js  c++  java
  • POJ 1275-Cashier Employment(差分约束系统)

    题目地址:POJ 1275

    题意: 给出一个超市24小时各须要R[i]个雇员工作,有N个雇员能够雇佣。他们開始工作时间分别为A[i],求须要的最少的雇员人数。

    思路:这个题的查约束太多了!简直是差评!只是也不是否能定这是道好题。

    设dis[i]为0-i小时内工作的人数(dis[24]即为所求)。r[i]为第(i-1)-i小时时须要在工作的人数,t[i]能够在第i-1小时開始工作。能够建立起下面约束不等式:

    0 <= dis[i]-dis[i-1] <= t[i];  1 <= i<= 24;
    dis[i] – dis[i-8] >= r[i];   8 <= i <= 24;
    dis[24] – (dis[16+i]-dis[i]) >= r[i];  1 <= i < 8;

    本以为这样就完了。呵呵。傻了吧,另一个

    dis[24]-dis[0] >= ans也是要作为一个约束不等式。加入(0, 24, ans)的边。sad。

    #include <stdio.h>
    #include <math.h>
    #include <string.h>
    #include <stdlib.h>
    #include <iostream>
    #include <sstream>
    #include <algorithm>
    #include <set>
    #include <queue>
    #include <stack>
    #include <map>
    using namespace std;
    typedef long long LL;
    const int inf=0x3f3f3f3f;
    const double pi= acos(-1.0);
    const double esp=1e-6;
    const int maxn=30;
    int dis[maxn],head[30];
    int r[maxn];
    int t[maxn];
    int cnt;
    struct node
    {
        int u,v,w;
        int next;
    }edge[10010];
    void add(int u,int v,int w)
    {
        edge[cnt].u=u;
        edge[cnt].v=v;
        edge[cnt].w=w;
        edge[cnt].next=head[u];
        head[u]=cnt++;
    }
    int Bellman_ford()
    {
        int i,j;
        memset(dis,inf,sizeof(dis));
        dis[24]=0;
        for(i=1;i<=24;i++){
            int flag=0;
            for(j=0;j<cnt;j++){
                int u=edge[j].u;
                int v=edge[j].v;
                if(dis[v]>dis[u]+edge[j].w){
                    dis[v]=dis[u]+edge[j].w;
                    flag=1;
                }
            }
            if(!flag) break;
        }
        for(i=0;i<cnt;i++){
            if(dis[edge[i].v]>dis[edge[i].u]+edge[i].w)
                return 0;
        }
        return 1;
    }
    int main()
    {
        int T,n,m,i;
        scanf("%d",&T);
        while(T--){
            memset(t,0,sizeof(t));
            memset(head,-1,sizeof(head));
            cnt=0;
            for(i=1;i<=24;i++)
                scanf("%d",&r[i]);
            scanf("%d",&n);
            for(i=1;i<=n;i++){
                scanf("%d",&m);
                t[m+1]++;
            }
            for(i=1;i<=24;i++){
                add(i,i-1,0);
                add(i-1,i,t[i]);
            }
            for(i=8;i<=24;i++)
                add(i,i-8,-r[i]);
            int ans=-1;
            int low=0,high=n;
            int Enum=cnt;//Enum保存已经加好的边数
            while(low<=high){//二分枚举答案
                cnt=Enum;
                int mid=(low+high)>>1;
                for(i=1;i<8;i++){
                    add(i,i+16,-r[i]+mid);
                }
                add(24,0,-mid);
                if(Bellman_ford()){//假设有解,那么再找更小的解
                    ans=mid;
                    high=mid-1;
                }
                else
                    low=mid+1;
            }
            if(ans==-1)
                puts("No Solution");
            else
                printf("%d
    ",ans);
        }
        return 0;
    }
    


  • 相关阅读:
    HTB-靶机-Charon
    第一篇Active Directory疑难解答概述(1)
    Outlook Web App 客户端超时设置
    【Troubleshooting Case】Exchange Server 组件状态应用排错?
    【Troubleshooting Case】Unable to delete Exchange database?
    Exchange Server 2007的即将生命周期,您的计划是?
    "the hypervisor is not running" 故障
    Exchange 2016 体系结构
    USB PE
    10 months then free? 10个月,然后自由
  • 原文地址:https://www.cnblogs.com/zhchoutai/p/6748250.html
Copyright © 2011-2022 走看看