现在的位置: 首页 > 综合 > 正文

poj1275 差分约束

2012年08月27日 ⁄ 综合 ⁄ 共 1403字 ⁄ 字号 评论关闭

    这道题很特殊,与以前做的差分约束完全不一样,因为在它的约束条件中竟然还有变量。

建图方法:

 

说明:

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;
}

 

 

抱歉!评论已关闭.