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

    思路:

    (S_i) 为前 (i) 个小时录取的人数, (num_i) 为第 (i) 个小时应聘的人数,(x_i) 为第 (i) 个小时雇佣的人数,可得:

    [egin{aligned}&(~1~)~~0leq x_ileq num_i=>0leq S_i-S_{i-1}leq num_i\\&(~2~)egin{cases}S_i-S_{i-1}geq R_i~(igeq 8)\S_i+S_{24}-S_{16+i}geq R_i=>S_i-S_{16+i}~geq R_i-S_{24}=R_i-sum(0< i<8)end{cases}\\&(~3~)~~S_{24}-S_0geq sumend{aligned} ]

    对于 ((3)) 因为 (S_{24}) 我们不知道它的值,但是它表示的就是 (sum) 即答案,所以枚举 (sum) (可以二分枚举,我懒得写了)

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <queue>
    #define maxn 100
    #define INF 0x3f3f3f3f
    using namespace std;
     
    int N;//个应聘者
    struct node {
        int u, v, w, next;
    };
     
    node edge[200000];
    int dist[maxn], head[maxn], used[maxn], cnt;
    bool vis[maxn];
    int work[maxn];//work[i]表示在第 i 个小时开始工作的人数
    int need[maxn];//应聘者中可以在第i个小时开始工作的人数
     
    void init (){
        cnt = 0;
        memset(head, -1, sizeof(head));
    }
     
    void add(int u, int v, int w){
        edge[cnt] = {u, v, w, head[u]};
        head[u] = cnt++;
    }
     
    void getmap(int sum){
        for(int i = 1; i <= 24; ++i){
            add(i - 1, i, 0);
            add(i, i - 1, -work[i]);
            if(i >= 8)
                add(i - 8, i, need[i]);
            else
                add(16 + i, i, need[i] - sum);
        }
        add(0, 24, sum);
    }
     
    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<queue> 
    
    using namespace std;
    const int N=100,INF=0x3f3f3f3f;
    struct node{
    	int u,v,w,nxt;
    }e[200010];
    
    int n;
    int dis[N],head[N],num[N],R[N],tot[N],cnt;//num[]表示第i小时应聘的人, R[]表示第i小时需要的人数 
    bool vis[N];
    
    inline void init(){
    	cnt=0;
    	memset(head,-1,sizeof(head));
    }
    
    inline void add(int u,int v,int w){
    	e[++cnt].u=u;
    	e[cnt].v=v;
    	e[cnt].w=w;
    	e[cnt].nxt=head[u];
    	head[u]=cnt;
    }
    
    inline void getsum(int sum){
    	for(int i=1;i<=24;i++){
    		add(i-1,i,0);
    		add(i,i-1,-num[i]);
    		if(i>=8) add(i-8,i,R[i]);
    		else add(16+i,i,R[i]-sum);
    	}
    	add(0,24,sum);
    }
    
    inline bool spfa(int sum){
    	for(int i=0;i<=24;i++){
    		dis[i]=-INF;
    		vis[i]=0;
    		tot[i]=0;
    	}
    	dis[0]=0;
    	vis[0]=1;
    	tot[0]=1;
    	queue<int>q;
    	q.push(0);
    	while(!q.empty()){
    		int u=q.front();
    		q.pop();
    		vis[u]=0;
    		for(int i=head[u];i!=-1;i=e[i].nxt){
    			int v=e[i].v;
    			int w=e[i].w;
    			if(dis[v]<dis[u]+w){
    				dis[v]=dis[u]+w;
    				if(!vis[v]){
    					vis[v]=1;
    					tot[v]++;
    					if(tot[v]>24) return 0;
    					q.push(v);
    				} 
    			}
    		}
    	}
    	return dis[24]==sum;
    }
    
    int main(){
    	int T;
    	scanf("%d",&T);
    	int flag;
    	while(T--){
    		flag=0;
    		memset(R,0,sizeof(R));
    		memset(num,0,sizeof(num));
    		for(int i=1;i<=24;i++) scanf("%d",&R[i]);
    		scanf("%d",&n);
    		for(int i=1,x;i<=n;i++){
    			scanf("%d",&x);
    			num[x+1]++;
    		}
    		for(int i=0;i<=n;i++){
    			init();
    			getsum(i);
    			if(spfa(i)){
    				flag=1;
    				printf("%d
    ",i);
    				break;
    			}
    		}
    		if(!flag) puts("No Solution");
    	} 
    	return 0;
    }
    
  • 相关阅读:
    fs.mkdir
    Node Buffer 利用 slice + indexOf 生成 split 方法
    class 类
    Proxy + Reflect 实现 响应的数据变化
    ivew 封装删除 对话框
    php调用js变量
    JS调用PHP 和 PHP调用JS的方法举例
    curl远程传输工具
    php 正则只保留 汉字 字母 数字
    php 发送与接收流文件
  • 原文地址:https://www.cnblogs.com/jasony/p/13555584.html
Copyright © 2011-2022 走看看