您的位置:首页 > 其它

POJ 1275 Cashier Employment(差分约束)

2013-03-08 11:48 411 查看
题目链接

详情请看黑书第306页。。。完全根据书做的,我把s[-1]改为s[24]了。

#include <cstdio>
#include <cstring>
#include <cmath>
#include <string>
#include <ctime>
#include <queue>
#include <vector>
using namespace std;
#define INF 10000000
struct node
{
int u,v,w,next;
}edge[100*100];
int first[101],in[101],dis[101],num[101];
int t;
int s[31],r[31],ti[31];
void CL()
{
t = 1;
memset(first,-1,sizeof(first));
}
void add(int u,int v,int w)
{
edge[t].u = u;
edge[t].v = v;
edge[t].w = w;
edge[t].next = first[u];
first[u] = t ++;
}
int spfa()
{
int i,u,v;
for(i = 0;i <= 24;i ++)
{
dis[i] = -INF;
in[i] = 0;
num[i] = 0;
}
queue<int> que;
que.push(24);
in[24] = 1;
dis[24] = 0;
num[24] = 1;
while(!que.empty())
{
u = que.front();
in[u] = 0;
que.pop();
for(i = first[u];i != -1;i = edge[i].next)
{
v = edge[i].v;
if(dis[v] < dis[u] + edge[i].w)
{
dis[v] = dis[u] + edge[i].w;
if(!in[v])
{
in[v] = 1;
que.push(v);
num[v] ++;
if(num[v] > 24)
return 1;
}
}
}
}
return 0;
}
int judge(int mid)
{
CL();
int i,j;
for(i = 1;i <= 23;i ++)
{
add(i-1,i,0);
add(i,i-1,-ti[i]);
}
add(24,0,0);
add(0,24,-ti[0]);
add(24,23,mid);
for(j = 0;j <= 23;j ++)
{
i = (j + 8)%24;
if(i > j)
add(j,i,r[i]);
else
add(j,i,r[i]-mid);
}
if(!spfa()&&dis[23] == mid)
return 1;
else
return 0;
}
int main()
{
int i,j,cas,n,maxz;
scanf("%d",&cas);
while(cas --)
{
maxz = 0;
for(i = 0;i < 24;i ++)
{
scanf("%d",&r[i]);
if(maxz < r[i])
maxz = r[i];
}
scanf("%d",&n);
for(i = 0;i < n;i ++)
{
scanf("%d",&j);
ti[j] ++;
}
for(i = 0;i <= n;i ++)
{
if(judge(i))
{
printf("%d\n",i);
break;
}
}
if(i == n+1)
printf("No Solution\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: