题意:
有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 }