裸的费用流啊。。。

建图:对于一个点p拆成两个p1和p2,S向p1连边,流量为1,费用为0;p2向T连边流量为1,费用为0

然后i1向a2到b2分别连边,不妨设i1向p2连边,流量为1,费用为|i - p| * ki

跑一下费用流,如果流量不为n,NIE!然后答案就是费用之和。。。

 

  1 /**************************************************************
  2     Problem: 1520
  3     User: rausen
  4     Language: C++
  5     Result: Accepted
  6     Time:1296 ms
  7     Memory:2380 kb
  8 ****************************************************************/
  9  
 10 #include <cstdio>
 11 #include <algorithm>
 12  
 13 using namespace std;
 14 const int N = 405;
 15 const int M = 1e5 + 5;
 16 const int inf = 1e9;
 17  
 18 struct edges {
 19     int next, to, f, cost;
 20     edges() {}
 21     edges(int _n, int _t, int _f, int _c) : next(_n), to(_t), f(_f), cost(_c) {}
 22 } e[M];
 23   
 24 int n, S, T;
 25 int first[N], tot = 1;
 26 int q[N], d[N], g[N];
 27 bool v[N];
 28  
 29 inline int read() {
 30     int x = 0, sgn = 1;
 31     char ch = getchar();
 32     while (ch < '0' || '9' < ch) {
 33         if (ch == '-') sgn = -1;
 34         ch = getchar();
 35     }
 36     while ('0' <= ch && ch <= '9') {
 37         x = x * 10 + ch - '0';
 38         ch = getchar();
 39     }
 40     return sgn * x;
 41 }
 42  
 43 inline void Add_Edges(int x, int y, int f, int c) {
 44     e[++tot] = edges(first[x], y, f, c), first[x] = tot;
 45     e[++tot] = edges(first[y], x, 0, -c), first[y] = tot;
 46 }
 47   
 48 inline int calc() {
 49     int flow = inf, x;
 50     for (x = g[T]; x; x = g[e[x ^ 1].to])
 51         flow = min(flow, e[x].f);
 52     for (x = g[T]; x; x = g[e[x ^ 1].to])
 53         e[x].f -= flow, e[x ^ 1].f += flow;
 54     return flow;
 55 }
 56  
 57 #define y e[x].to
 58 bool spfa() {
 59     int x, now, l, r;
 60     for (x = 1; x <= T; ++x)
 61         d[x] = inf;
 62     d[S] = 0, v[S] = 1, q[0] = S;
 63     for(l = r = 0; l != (r + 1) % N; ) {
 64         now = q[l], ++l %= N;
 65         for (x = first[now]; x; x = e[x].next) {
 66             if (d[now] + e[x].cost < d[y] && e[x].f) {
 67                 d[y] = d[now] + e[x].cost, g[y] = x;
 68                 if (!v[y]) {
 69                     v[y] = 1;
 70                     if (d[y] < d[q[l]])
 71                         q[(l += N - 1) %= N] = y;
 72                     else q[++r %= N] = y;
 73                 }
 74             }
 75         }
 76         v[now] = 0;
 77     }
 78     return d[T] != inf;
 79 }
 80 #undef y
 81  
 82 inline int work() {
 83     static int res, tot;
 84     res = 0, tot = 0;
 85     while (spfa()) {
 86         tot += calc();
 87         res += d[T];
 88     }
 89     if (tot == n) printf("%d\n", res);
 90     else puts("NIE");
 91 }
 92  
 93 int main() {
 94     int i, j, a, b, k, m;
 95     n = read(), S = 2 * n + 1, T = S + 1;
 96     for (i = 1; i <= n; ++i)
 97         Add_Edges(S, i, 1, 0), Add_Edges(i + n, T, 1, 0);
 98     for (i = 1; i <= n; ++i) {
 99         m = read(), a = read(), b = read(), k = read();
100         for (j = a; j <= b; ++j)
101             Add_Edges(i, n + j, 1, abs((j - m) * k));
102     }
103     work();
104     return 0;
105 }
View Code

 

posted on 2015-03-21 22:59  Xs酱~  阅读(167)  评论(0编辑  收藏  举报