poj 1275(差分约束)
2013-04-04 16:12
393 查看
题意:1天24小时,每个小时需要售货员人r[i]个(r[1]表示从0:00-1:00,,等等),n个工人应聘,每个人开始工作时间为st[i],都工作8个小时。问最少的应聘人数。
分析:为了防止出现负数,在这里把标号设为1-24,并且设0为虚点。设x[i]是实际雇用的i时刻开始工作的员工数 ,r[i]是题目需要的i时刻正在工作的最少员工数.
设s[i] = x[1] + x[2] + …… + x[i] ,s[0]=0.
则s[i]表示1-i这段时间开始工作的员工数
再设t[i]表示i时刻开始工作的最多可以雇用的员工数
∴有0 <= x[i] <= t[i]
即 0 <= s[i] - s[i-1] <= t[i]
由于是求最小值,所以用最长路 。
则有:①s[i] - s[i-1] >= 0;②s[i-1] - s[i] >= -t[i]; (1 <= i <= 24)
由于员工可以持续工作8个小时(r[i]是i时刻正在工作的最少人数)
∴x[i-7] + x[i-6] + …… + x[i] >= r[i]【i-7开始工作的人在i时刻也在工作,其他同理】
即:③s[i] - s[i-8] >= r[i] (8 <= i <= 24)
或者:(x[i+17] + …… + x[24]) + (x[1] + x[2] + …… + x[i]) >= r[i]; (i<=7)
则:s[24] - s[i+16] + s[i] >= r[i];
整理一下:④s[i] - s[i+16] >= r[i] - s[24];(1 <= i <= 7)
显然④式跟一般的差分约束式子不太一样。因为s[24]是未知的。所以我们可以去找一个④的一个充分条件来代替④式,同时使得式子是符合差分约束形式的。
即:⑤s[24] >= k
⑥s[i] - s[i+16] >= r[i] - k
显然满足①②③⑤⑥式的最小的k即为所求。枚举或二分k判断是否有正环即可。
分析:为了防止出现负数,在这里把标号设为1-24,并且设0为虚点。设x[i]是实际雇用的i时刻开始工作的员工数 ,r[i]是题目需要的i时刻正在工作的最少员工数.
设s[i] = x[1] + x[2] + …… + x[i] ,s[0]=0.
则s[i]表示1-i这段时间开始工作的员工数
再设t[i]表示i时刻开始工作的最多可以雇用的员工数
∴有0 <= x[i] <= t[i]
即 0 <= s[i] - s[i-1] <= t[i]
由于是求最小值,所以用最长路 。
则有:①s[i] - s[i-1] >= 0;②s[i-1] - s[i] >= -t[i]; (1 <= i <= 24)
由于员工可以持续工作8个小时(r[i]是i时刻正在工作的最少人数)
∴x[i-7] + x[i-6] + …… + x[i] >= r[i]【i-7开始工作的人在i时刻也在工作,其他同理】
即:③s[i] - s[i-8] >= r[i] (8 <= i <= 24)
或者:(x[i+17] + …… + x[24]) + (x[1] + x[2] + …… + x[i]) >= r[i]; (i<=7)
则:s[24] - s[i+16] + s[i] >= r[i];
整理一下:④s[i] - s[i+16] >= r[i] - s[24];(1 <= i <= 7)
显然④式跟一般的差分约束式子不太一样。因为s[24]是未知的。所以我们可以去找一个④的一个充分条件来代替④式,同时使得式子是符合差分约束形式的。
即:⑤s[24] >= k
⑥s[i] - s[i+16] >= r[i] - k
显然满足①②③⑤⑥式的最小的k即为所求。枚举或二分k判断是否有正环即可。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <queue> using namespace std; const int inf = 0x3f3f3f3f; const int maxn = 25; int n; int r[maxn], t[maxn], s[maxn]; struct edge { int v, c; edge(){} edge(int v, int c):v(v), c(c){} }; vector <edge> adj[maxn]; void build(int mid) { memset(adj, 0, sizeof(adj)); for (int i = 0; i <24; ++i) { adj[i].push_back(edge(i + 1, 0)); adj[i + 1].push_back(edge(i, -t[i+1])); } for (int i = 8; i <= 24; ++i) { adj[i - 8].push_back(edge(i, r[i])); } for (int i = 1; i <= 7; ++i) { adj[i+16].push_back(edge(i, r[i] - mid)); } adj[0].push_back(edge(24, mid)); } int dis[maxn],cnt[maxn]; bool relax(int u, int v, int c) { if (dis[v] < dis[u] + c) { dis[v] = dis[u] + c; return true; } return false; } bool spfa(int src) { bool vis[maxn]; memset(vis, 0, sizeof(vis)); memset(cnt, 0, sizeof(cnt)); for (int i = 0; i < maxn ; ++i) dis[i] = -inf; dis[src] = 0; vis[src] = 1; queue <int> q; q.push(src); while (!q.empty()) { int pre = q.front();q.pop(); vis[pre] = 0; for (int i = 0; i < adj[pre].size(); ++i) { if(relax(pre, adj[pre][i].v, adj[pre][i].c) && !vis[adj[pre][i].v]) { if((++cnt[adj[pre][i].v]) > 25) return false; q.push(adj[pre][i].v); vis[adj[pre][i].v] = 1; } } } return true; } int main() { int test; scanf("%d", &test); while(test--) { memset(r, 0, sizeof(r)); memset(t, 0, sizeof(t)); memset(s, 0, sizeof(s)); for (int i = 1; i <= 24; ++i) scanf("%d", &r[i]); scanf("%d", &n); for (int i = 1; i <= n; ++i) { int x; scanf("%d", &x); ++t[x + 1]; } int low = 0, high = n + 1, ans = -1; while (high >= low) { int mid = (high + low) >> 1; build(mid); if(spfa(0)) { ans = mid; high = mid - 1; } else low = mid + 1; } /*for (int i = 0; i <= n; ++ i) { build(i); //cout<<i<<endl; if(spfa(0)) { ans = i; break; } }*/ if(ans == -1) printf("No Solution\n"); else printf("%d\n", ans); } return 0; }
相关文章推荐
- poj1275 差分约束
- POJ 1275--Cashier Employment【差分约束,经典建边】
- POJ 1275 Cashier Employment(差分约束)
- POJ1275 Cashier Employment 【二分 + 差分约束】
- ACM: 图论题 poj 1275 差分约束题
- POJ1275 Cashier Employment(差分约束)
- POJ 1275 Cashier Employment (差分约束 + spfa)
- 关于差分约束的一些总结和题解。(poj 1364 ,3159, 2983, 3169 ,1201 ,1716 ,1275)
- poj 1275 Cashier Employment 差分约束
- poj 1275(约束差分求解:汇总)
- Poj1275 差分约束
- POJ 1275 Cashier Employment(差分约束)
- poj 1275 Cashier Employment - 差分约束 - 二分答案
- poj 1275 Cashier Employment 【差分约束】【经典建模】 【最短路求法 + 最长路求法】
- poj 1275 Cashier Employment 差分约束
- poj1275 Cashier Employment (差分约束)
- POJ 1275 Cashier Employment 挺难的差分约束题
- POJ 1275 Cashier Employment (差分约束 二分)
- poj 1275 差分约束
- POJ 1275 Cashier Employment 挺难的差分约束题