HDU 4780 Candy Factory

Posted mingsd

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

 

以上是关于HDU 4780 Candy Factory的主要内容,如果未能解决你的问题,请参考以下文章

HDU4465 Candy

HDU 5654 xiaoxin and his watermelon candy 离线树状数组

hdu 5380 Travel with candy(双端队列)

dp hdu5653 xiaoxin and his watermelon candy

hdu 5654 xiaoxin and his watermelon candy 树状数组维护区间唯一元组

线段树+离线 hdu5654 xiaoxin and his watermelon candy