• HDU


    题意:M台机器要生产n个糖果,糖果i的生产区间在(si, ti),花费是k(pi-si),pi是实际开始生产的时间机器,j从初始化到生产糖果i所需的时间Cij,花费是Dij,任意机器从生产糖果i到生产糖果j,需花费时间Eij,花费Fij求生产完所有糖果所需的最小时间?
    题解:先把糖果拆点,s向i糖果连流量为1,费用为0,i+n糖果向t连流量为1,费用为0,n
    2+i机器向t连流量为1,费用为0的边,如果i能流向j,那么j连i+n一条边流量为1,费用为(ti-sj)k+dij,如果机器j能流向i+2n,那么连一条边流量为1,费用为(p-s)*k+d,假设i流向了j,那么说明j在i之后生产,而且保证了每台机器只生产一种糖果

    //#pragma GCC optimize(2)
    //#pragma GCC optimize(3)
    //#pragma GCC optimize(4)
    //#pragma GCC optimize("unroll-loops")
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define db double
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pll pair<ll,ll>
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    //#define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define Max(a,b) ((a)>(b)?(a):(b))
    #define Min(a,b) ((a)<(b)?(a):(b))
    #define fin freopen("a.txt","r",stdin)
    #define fout freopen("a.txt","w",stdout)
    #define fio ios::sync_with_stdio(false);cin.tie(0)
    template<typename T>
    inline T const& MAX(T const &a,T const &b){return a>b?a:b;}
    template<typename T>
    inline T const& MIN(T const &a,T const &b){return a<b?a:b;}
    inline void add(ll &a,ll b){a+=b;if(a>=mod)a-=mod;}
    inline void sub(ll &a,ll b){a-=b;if(a<0)a+=mod;}
    inline ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
    inline ll qp(ll a,ll b){ll ans=1;while(b){if(b&1)ans=ans*a%mod;a=a*a%mod,b>>=1;}return ans;}
    inline ll qp(ll a,ll b,ll c){ll ans=1;while(b){if(b&1)ans=ans*a%c;a=a*a%c,b>>=1;}return ans;}
    
    using namespace std;
    
    const double eps=1e-8;
    const ll INF=0x3f3f3f3f3f3f3f3f;
    const int N=300+10,maxn=400000+10,inf=0x3f3f3f3f;
    
    struct edge{
        int to,Next,c;
        int cost;
    }e[maxn];
    int cnt,head[N];
    int s,t;
    int dis[N],pre[N],path[N];
    bool vis[N];
    void add(int u,int v,int c,int cost)
    {
        e[cnt].to=v;
        e[cnt].c=c;
        e[cnt].cost=cost;
        e[cnt].Next=head[u];
        head[u]=cnt++;
        e[cnt].to=u;
        e[cnt].c=0;
        e[cnt].cost=-cost;
        e[cnt].Next=head[v];
        head[v]=cnt++;
    }
    bool spfa()
    {
        memset(pre,-1,sizeof pre);
        memset(dis,inf,sizeof dis);
        memset(vis,0,sizeof vis);
        dis[s]=0;
        vis[s]=1;
        queue<int>q;
        q.push(s);
        while(!q.empty())
        {
            int x=q.front();
            q.pop();
            vis[x]=0;
            for(int i=head[x];~i;i=e[i].Next)
            {
                int te=e[i].to;
                if(e[i].c>0&&dis[x]+e[i].cost<dis[te])
                {
                    dis[te]=dis[x]+e[i].cost;
                    pre[te]=x;
                    path[te]=i;
                    if(!vis[te])q.push(te),vis[te]=1;
                }
            }
        }
        return pre[t]!=-1;
    }
    int n,m,k;
    int mincostmaxflow()
    {
        int cost=0,flow=0;
        while(spfa())
        {
            int f=inf;
            for(int i=t;i!=s;i=pre[i])
                if(e[path[i]].c<f)
                   f=e[path[i]].c;
            flow+=f;
            cost+=dis[t]*f;
            for(int i=t;i!=s;i=pre[i])
            {
                e[path[i]].c-=f;
                e[path[i]^1].c+=f;
            }
        }
        if(flow!=n)return -1;
        return cost;
    }
    void init()
    {
        memset(head,-1,sizeof head);
        cnt=0;
    }
    int cans[N],cant[N],ti[N][N];
    int main()
    {
        while(~scanf("%d%d%d",&n,&m,&k))
        {
            if(!n&&!m&&!k)break;
            init();
            s=2*n+m+1,t=2*n+m+2;
            for(int i=1;i<=m;i++)add(2*n+i,t,1,0);
            for(int i=1;i<=n;i++)
            {
                scanf("%d%d",&cans[i],&cant[i]);
                add(s,i,1,0);add(i+n,t,1,0);
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=m;j++)
                    scanf("%d",&ti[i][j]);
            for(int i=1;i<=n;i++)
            {
                for(int j=1,x;j<=m;j++)
                {
                    scanf("%d",&x);
                    if(ti[i][j]<cant[i])
                    {
                        add(i,2*n+j,1,max(0,ti[i][j] - cans[i])*k+x);
                    }
                }
            }
            for(int i=1;i<=n;i++)
                for(int j=1;j<=n;j++)
                    scanf("%d",&ti[i][j]);
            for(int i=1;i<=n;i++)
            {
                for(int j=1,x;j<=n;j++)
                {
                    scanf("%d",&x);
                    if(cant[i] + ti[i][j] < cant[j] && i != j)add(j,n+i,1,max(0,cant[i] + ti[i][j] - cans[j])*k+x);
                }
            }
            printf("%d
    ",mincostmaxflow());
        }
        return 0;
    }
    /********************
    3 2 1
    4 7
    2 4
    8 9
    4 4
    3 3
    3 3
    2 8
    12 3
    14 6
    -1 1 1
    1 -1 1
    1 1 -1
    -1 5 5
    5 -1 5
    5 5 -1
    ********************/
    
  • 相关阅读:
    终于有人把MYSQL索引讲清楚了
    计算机基础知识总结与操作系统 PDF 下载
    java电子书python电子书等PDF下载方式
    redis布隆过滤器
    IntelliJ IDEA 2020.1 激活教程,亲测可用
    Another Redis DeskTop Manager一款稳定全新的redis连接工具
    一文吃透redis持久化,妈妈再也不担心我面试过不了!
    ES6 运算符
    If-Else的5种方法从入门到高级示例
    ES6中 的类(class)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9719392.html
Copyright © 2020-2023  润新知