您的位置:首页 > 其它

poj1275 差分约束

2013-03-30 15:45 295 查看
这道题很特殊,与以前做的差分约束完全不一样,因为在它的约束条件中竟然还有变量。

建图方法:

说明:

r[i]-------第i小时需要的人

t[i]-------第i小时去应聘的人

s[i]-------第0到i小时总共招聘的人

约束系统:

1.s[i]-s[i-1]<=t[i]

2.s[i]-s[i-1]>=0

3.s[j]-s[i]>=r[i],j=(i+8)%24,j>i

4.s[j]+sum-s[i]>=r[i],j=(i+8)%24,j<i

5.s[24]-s[0]>=sum

算法思想:Bellman_Ford()+枚举sum (此处也可以用二分枚举,我是直接枚举的)

#include<iostream>
#include<cstdio>

using namespace std;
struct{
int u,v,w;
}e[200];
int t[25],r[25],s[25],d[25];
int n,m;

bool relax(int u,int v,int w)
{
if(d[u]+w>d[v])
{
d[v]=d[u]+w;
return true;
}
return false;
}

bool Bellman_Ford()
{
int i,j;
bool flag=true;
for(i=0;i<=n;i++)
d[i]=100000000;
d[0]=0;
for(i=0;i<n&&flag;i++)
{
flag=false;
for(j=0;j<m;j++)
if(relax(e[j].u,e[j].v,e[j].w))
flag=true;
}
if(!flag)
return true;
for(j=0;j<m;j++)
if(relax(e[j].u,e[j].v,e[j].w))
return false;
return true;
}

int main()
{
int Case,sum;
int i,j;
scanf("%d",&Case);
while(Case--)
{
for(i=1;i<=24;i++)
{
t[i]=0;
scanf("%d",r+i);
}
scanf("%d",&n);
while(n--)
{
int time;
scanf("%d",&time);
t[time+1]++;
}
for(i=1;i<=24;i++)
s[i]=s[i-1]+t[i];

///////////////////////////
//此部分建固有边
m=0;
n=24;
for(i=1;i<=24;i++)
{
e[m].u=i-1;
e[m].v=i;
e[m].w=0;
m++;
e[m].u=i;
e[m].v=i-1;
e[m].w=-t[i];
m++;
}
for(i=1;i<=16;i++)
{
j=i+8;
e[m].u=i;
e[m].v=j;
e[m].w=r[j];
m++;
}
//////////////////////////////
int mm=m;
for(sum=0;sum<=s[24];sum++)
{
m=mm;
for(i=17;i<=24;i++)
{
j=i-16;
e[m].u=i;
e[m].v=j;
e[m].w=r[j]-sum;
m++;
}
e[m].u=0;
e[m].v=24;
e[m].w=sum;
m++;
if(Bellman_Ford())
break;
}
if(sum<=s[24])
printf("%d\n",sum);
else
printf("No Solution\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: