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\n", MaxFlow());
138     }
139     return 0;
140 }
View Code

 

posted @ 2018-09-28 19:10  Schenker  阅读(246)  评论(0编辑  收藏  举报