poj1275差分约束

设num[i]  为在i时刻可以工作的应聘人数

x[i]  在i时刻招聘的人数

m[i] 在i时刻要求最少的工作人数

由题意建立起约束:

(1)0 <= x[i] <= num[i]

(2)x[i-7] + x[i-6 ]+.....+ x[i] >= m[i] (因为工作8小时) (i<7时要特殊考虑)

设s[i] = x[1] + x[2] + .....+ x[i]  从第0时刻到第i时刻招聘的总人数

将约束转化为 差分形式:

由(1):

s[i] - s[i-1] >= 0  1 <= i <= 24  ( 第i时刻可能不招人)

s[i-1] - s[i] >= -num[i]    1 <= i <= 24 

由(2):

s[i] - s[i-8] >= m[i]  9 <= i <= 24 (不受一天的影响)

s[i] - s[i+16] >= m[i] - s[24] 1 <= i <= 8 (受上一天的影响)

特加条件: s[24] - s[0] >= ans 

不妨假设s[24]为ans,以0点为源点跑最长路有解,且s[24]=ans。说明此解有效。

所以最长路作为二分搜索的判断条件。搜索可行解。

#include 
#include 
#include 
#include 
#include 
#define MAX_N 25
#define INF 0x7fffffff
using namespace std;
struct edge{int to,val;
};
bool inque[MAX_N];
int dist[MAX_N];
int vis[MAX_N];
int s[MAX_N];
int num[MAX_N];
int m[MAX_N];
vector g[MAX_N];
int init()
{for(int i=0;i= 0// s[i-1] – s[i] >= –num[i]// s[i] – s[i-8] >= r[i], 9 <= i <= 24// s[i] – s[i+16] >= r[i] – s[24],  1<= i <= 8// s[24] – s[0] >= ansfor(int i=1;i<=24;++i)add_edge(i-1,i,0);for(int i=1;i<=24;++i)add_edge(i,i-1,-num[i]);for(int i=9;i<=24;++i)add_edge(i-8,i,m[i]);for(int i=1;i<=8;++i)add_edge(i+16,i,m[i]-ans);add_edge(0,24,ans);
}
bool spfa(int start,int res)
{queue que;for(int i=0;iMAX_N) return false;for(int i=0;i=1){int mid=(rb+lb)/2;init();bulidGraph(mid);if(spfa(0,mid))rb=mid;else lb=mid+1;}return rb;
}
int main()
{int t;scanf("%d",&t);while(t--){for(int i=1;i<=24;++i)scanf("%d",&m[i]);int n;memset(num,0,sizeof(n));scanf("%d",&n);int u,rb=0;for(int i=0;i




本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部