hdu 1529 差分约束(Bellman_Ford)
Problem : 1529 ( Cashier Employment ) Judge Status : Accepted
RunId : 1599582 Language : C++ Author : va
Code Render Status : Rendered By HDOJ C++ Code Rander Version 0.01 Beta
RunId : 1599582 Language : C++ Author : va
Code Render Status : Rendered By HDOJ C++ Code Rander Version 0.01 Beta
#include <cstdio> #include <cstring> const int MAXN = 1010; typedef struct { int from, to, cost; }Edge; int min_need[25]; //各时刻最少需要工作人数 int now_can[25]; //各时刻能*开始*工作人数 int dis[25]; //各时刻实际需要人数 Edge e[MAXN]; int n, t, oldt; //初始化 void init() { int i; memset(now_can, 0, sizeof(now_can)); for (i = 0; i < 24; ++i) { scanf("%d", &min_need[i]); } scanf("%d", &n); for (i = 0; i < n; ++i) { scanf("%d", &t); now_can[t]++; } } //建图 void construct_graphic() { int i; t = 0; for (i = 1; i < 24; ++i) { e[t].from = i; e[t].to = i-1; e[t++].cost = 0; } for (i = 1; i < 24; ++i) { e[t].from = i-1; e[t].to = i; e[t++].cost = now_can[i]; } for (i = 8; i < 24; ++i) { e[t].from = i; e[t].to = i-8; e[t++].cost = -min_need[i]; } oldt = t; } bool bellman_ford(int ans) { int i, j; t = oldt; for (i = 0; i <= 7; ++i) { e[t].from = i; e[t].to = i+16; e[t++].cost = ans - min_need[i]; } memset(dis, 0, sizeof(dis));//赋0 即构造新的不等式组xi-x0<=0 x0为起点 bool flag = true; for (i = 0; i <= 25 && flag; ++i) //多了1次循环 是为了判负圈的情况 { flag = false; for (j = 0; j < t; ++j) { if (dis[e[j].from] + e[j].cost < dis[e[j].to]) { dis[e[j].to] = dis[e[j].from] + e[j].cost; flag = true; } } } if (flag) { return false; } else { return true; } } //对s[23]二分 void binary_search() { int high, low, mid, ans = -1; high = n, low = 0; while (low < high) { mid = (low + high)/2; if (bellman_ford(mid)) { ans = mid; high = mid; } else { low = mid+1; } } if (ans == -1) { puts("No Solution"); } else { printf("%d\n", ans); } } int main() { int T; scanf("%d", &T); while (T--) { init(); construct_graphic(); binary_search(); } return 0; }