• poj1275 差分约束


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

    建图方法:

    说明:

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


     

  • 相关阅读:
    selenium headlesschrome下设置最大窗口模式
    lxml简明教程
    lxml etree的一个问题
    pycharm导入模块的时候遇到的两个错误
    linux下安装python
    【Android进阶学习】shape和selector的结合使用
    ANDROID资源文件【转】
    android 屏幕适配问题【转】
    android UI进阶之style和theme的使用
    Android入门第十六篇之Style与Theme [转]
  • 原文地址:https://www.cnblogs.com/javawebsoa/p/2990450.html
Copyright © 2020-2023  润新知