zoukankan      html  css  js  c++  java
  • HDU 4780 Candy Factory

    Candy Factory

    题意:

    有n种糖果,要求每种糖果都要生产刚好一颗

    遵循如下规则:

    1.糖果i的生产区间在(si, ti),花费是k*(pi-si),pi是实际开始生产的时间,pi需要在区间[si, ti-1]以内.

    2.每个机器第一次使用的时候都有一个初始化时间,机器 j 从初始化到生产糖果 i 所需的时间 C[i][j],花费是D[i][j].

    3.任意机器从生产糖果 i 到生产糖果 j,需花费时间E[i][j], 花费F[i][j] 求生产完所有糖果所需的最小花费。

    一种很特殊的建图方式。

    s 连向 每种糖果 f = 1 cost = 0

    每种糖果连向每个机器  f = 1 cost = 计算之后的花费

    每个机器 再与 t 连边 f = 1 cost = 0

    生产完 a 糖果之后能生产 b 糖果的话 就把  b 连向 a 的拆点 f = 1, cost = 计算之后的花费

    再把 每个糖果的拆点连向 t  f = 1, cost = 0

    再跑一遍最小费用流,就好了,注意的就是看流量有没有流满 没有流满就输出-1

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
      4 #define LL long long
      5 #define ULL unsigned LL
      6 #define fi first
      7 #define se second
      8 #define pb push_back
      9 #define lson l,m,rt<<1
     10 #define rson m+1,r,rt<<1|1
     11 #define lch(x) tr[x].son[0]
     12 #define rch(x) tr[x].son[1]
     13 #define max3(a,b,c) max(a,max(b,c))
     14 #define min3(a,b,c) min(a,min(b,c))
     15 typedef pair<int,int> pll;
     16 const int inf = 0x3f3f3f3f;
     17 const LL INF = 0x3f3f3f3f3f3f3f3f;
     18 const LL mod =  (int)1e9+7;
     19 const int N = 500;
     20 const int M = N*N;
     21 int n, m, k;
     22 int C[N][N], D[N][N], E[N][N], F[N][N];
     23 int l[N], r[N];
     24 
     25 int px[N], py[N];
     26 int head[N], to[M], ct[M], w[M], nt[M];
     27 int d[N], vis[N];
     28 int pre[N], id[N];
     29 int s, t, tot;
     30 
     31 void add(int u, int v, int val, int cost){
     32     to[tot] = v;
     33     ct[tot] = cost;
     34     w[tot] = val;
     35     nt[tot] = head[u];
     36     head[u] = tot++;
     37 
     38     to[tot] = u;
     39     ct[tot] = -cost;
     40     w[tot] = 0;
     41     nt[tot] = head[v];
     42     head[v] = tot++;
     43 }
     44 void init(){
     45     memset(head, -1, sizeof(head));
     46     tot = 0;
     47 }
     48 int spfa(){
     49     queue<int> q;
     50     memset(d, inf, sizeof(d));
     51     memset(vis, 0, sizeof(vis));
     52     memset(pre, -1, sizeof(vis));
     53     d[s] = 0;
     54     q.push(s);
     55     while(!q.empty()){
     56         int u = q.front(); q.pop();
     57         vis[u] = 0;
     58         for(int i = head[u]; ~i; i = nt[i]){
     59             if(w[i] > 0 && d[to[i]] > d[u] + ct[i]){
     60                 d[to[i]] = d[u] + ct[i];
     61                 pre[to[i]] = u;
     62                 id[to[i]] = i;
     63                 if(!vis[to[i]]){
     64                     vis[to[i]] = 1;
     65                     q.push(to[i]);
     66                 }
     67             }
     68         }
     69 
     70     }
     71     return d[t] < inf;
     72 }
     73 int MaxFlow(){
     74     int Mi = inf;
     75     int sum = 0;
     76     int tt = 0;
     77     while(spfa()){
     78         Mi = inf;
     79         for(int i = t; i != s; i = pre[i])
     80             Mi = min(Mi, w[id[i]]);
     81         for(int i = t; i != s; i = pre[i]){
     82             w[id[i]] -= Mi;
     83             w[id[i]^1] += Mi;
     84         }
     85         tt += Mi;
     86         sum += d[t];
     87     }
     88 
     89     if(tt < n) sum = -1;
     90     return sum;
     91 }
     92 int main(){
     93     while(~scanf("%d%d%d", &n, &m, &k) && n+m+k){
     94         for(int i = 1; i <= n; i++) scanf("%d%d", &l[i], &r[i]);
     95         for(int i = 1; i <= n; i++)
     96             for(int j = 1; j <= m; j++)
     97                 scanf("%d", &C[i][j]);
     98         for(int i = 1; i <= n; i++)
     99             for(int j = 1; j <= m; j++)
    100                 scanf("%d", &D[i][j]);
    101         for(int i = 1; i <= n; i++)
    102             for(int j = 1; j <= n; j++)
    103                 scanf("%d", &E[i][j]);
    104         for(int i = 1; i <= n; i++)
    105             for(int j = 1; j <= n; j++)
    106                 scanf("%d", &F[i][j]);
    107         init();
    108         s = 0, t = n*2 + m + 1;
    109         for(int i = 1; i <= n; i++){
    110             add(s, i, 1, 0);
    111             add(i+n, t, 1, 0);
    112         }
    113         for(int i = 1; i <= m; i++)
    114             add(n*2+i, t, 1, 0);
    115         //cout << tot << endl;
    116         for(int i = 1; i <= n; i++)
    117             for(int j = 1; j <= n; j++){
    118                 if(i == j) continue;
    119                 int tt = r[i] + E[i][j];
    120                 if(tt < r[j]){
    121                     int p = tt - l[j];
    122                     if(p < 0) p = 0;
    123                     add(j, i+n, 1, p*k+F[i][j]);
    124                 }
    125         }
    126         //cout << tot << endl;
    127         for(int i = 1; i <= n; i++)
    128             for(int j = 1; j <= m; j++){
    129                 int tt = C[i][j];
    130                 if(tt < r[i]){
    131                     int p = tt - l[i];
    132                     if(p < 0) p = 0;
    133                     add(i, 2*n+j, 1, p*k + D[i][j]);
    134                 }
    135         }
    136 
    137         printf("%d
    ", MaxFlow());
    138     }
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    无旋转Treap简介
    bzoj 4318 OSU!
    bzoj 1419 Red is good
    bzoj 4008 亚瑟王
    bzoj 1014 火星人prefix
    更多的莫队
    bzoj 3489 A simple rmq problem
    洛谷 2056 采花
    NOIP 2017 游(划水)记
    UVa 11997 K Smallest Sums
  • 原文地址:https://www.cnblogs.com/MingSD/p/9720343.html
Copyright © 2011-2022 走看看