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;
}
浙公网安备 33010602011771号