zoukankan      html  css  js  c++  java
  • CF132E Bits of merry old England

    解:略一思索:网络流啊!(别问我是怎么想到的......)

    发现跟志愿者招募有点像。于是把图建一下,在下面开一条通道,但是每个点又都要经过,这时我们就无脑上下界一波。

    通道向点连边,有费用。每个点向它下一次出现的点连边,费用0。每个点还向通道连边,费用0。

    上下界费用流跑一下就出来费用了。然后是输出方案,看哪些边有流量,直接模拟。

      1 #include <bits/stdc++.h>
      2 
      3 const int N = 1010, INF = 0x3f3f3f3f;
      4 
      5 struct Edge {
      6     int nex, v, c, len;
      7     Edge(int Nex = 0, int V = 0, int C = 0, int L = 0) {
      8         nex = Nex;
      9         v = V;
     10         c = C;
     11         len = L;
     12     }
     13 }edge[1000000]; int tp = 1;
     14 
     15 int X[N];
     16 
     17 struct Node {
     18     int p, v;
     19     bool f; /// 0 print  1 change
     20     Node(int P = 0, int V = 0, bool F = 0) {
     21         p = P;
     22         v = V;
     23         f = F;
     24     }
     25     inline void out() {
     26         if(!f) {
     27             printf("print("); putchar('a' + p - 1); printf(")
    ");
     28         }
     29         else {
     30             putchar('a' + p - 1); printf("=%d
    ", X[v]);
     31         }
     32         return;
     33     }
     34 }stk[N]; int top;
     35 
     36 int xx, Last[N], nex[N], in[N], e[N], tag[N];
     37 int n, m, a[N], val[N], pre[N], vis[N], flow[N], d[N];
     38 std::queue<int> Q;
     39 
     40 inline void Max(int &a, const int &b) {
     41     a < b ? a = b : 0;
     42     return;
     43 }
     44 
     45 inline void add(int x, int y, int z, int w) {
     46 //    printf("add : %d %d %d %d
    ", x, y, z, w);
     47     edge[++tp] = Edge(e[x], y, z, w);
     48     e[x] = tp;
     49     edge[++tp] = Edge(e[y], x, 0, -w);
     50     e[y] = tp;
     51     return;
     52 }
     53 
     54 inline bool SPFA(int s, int t) {
     55     static int Time = 0; ++Time;
     56     memset(d, 0x3f, sizeof(d));
     57     Q.push(s);
     58     vis[s] = Time;
     59     flow[s] = INF;
     60     d[s] = 0;
     61     while(!Q.empty()) {
     62         int x = Q.front();
     63         Q.pop();
     64         vis[x] = 0;
     65 //        printf("  x = %d  d[x] = %d 
    ", x, d[x]);
     66         for(int i = e[x]; i; i = edge[i].nex) {
     67             int y = edge[i].v;
     68             if(d[y] > d[x] + edge[i].len && edge[i].c) {
     69                 d[y] = d[x] + edge[i].len;
     70 //                printf("    y = %d  d[y] = %d 
    ", y, d[y]);
     71                 flow[y] = std::min(flow[x], edge[i].c);
     72                 pre[y] = i;
     73                 if(vis[y] != Time) {
     74                     vis[y] = Time;
     75                     Q.push(y);
     76                 }
     77             }
     78         }
     79     }
     80     return d[t] < INF;
     81 }
     82 
     83 inline void update(int s, int t) {
     84     int f = flow[t];
     85 //    printf("update : %d ", t);
     86     while(t != s) {
     87         int i = pre[t];
     88         edge[i].c -= f;
     89         edge[i ^ 1].c += f;
     90         t = edge[i ^ 1].v;
     91 //        printf("%d ", t);
     92     }
     93 //    printf("
    ");
     94     return;
     95 }
     96 
     97 inline int solve(int s, int t, int &cost) {
     98     int ans = 0; cost = 0;
     99 //    printf("solve : %d %d 
    ", s, t); int i = 0;
    100     while(SPFA(s, t)) {
    101 //        printf("loop : %d flow = %d d = %d 
    ", ++i, flow[t], d[t]);
    102         ans += flow[t];
    103         cost += flow[t] * d[t];
    104         update(s, t);
    105     }
    106 //    printf("ans = %d cost = %d
    ", ans, cost);
    107     return ans;
    108 }
    109 
    110 /*
    111 7 2
    112 1 2 2 4 2 1 2
    113 ------------- 11 4
    114 6 3
    115 1 2 3 1 2 3
    116 -------------  9 4
    117 */
    118 
    119 int main() {
    120     scanf("%d%d", &n, &m);
    121     for(int i = 1; i <= n; i++) {
    122         scanf("%d", &a[i]);
    123         int x = a[i];
    124         while(x) {
    125             x -= x & (-x);
    126             val[i]++;
    127         }
    128         X[i] = a[i];
    129     }
    130     std::sort(X + 1, X + n + 1);
    131     xx = std::unique(X + 1, X + n + 1) - X - 1;
    132 //    printf("xx = %d 
    ", xx);
    133     for(int i = 1; i <= n; i++) {
    134         a[i] = std::lower_bound(X + 1, X + xx + 1, a[i]) - X;
    135 //        printf("a %d = %d 
    ", i, a[i]);
    136     }
    137     for(int i = n; i >= 1; i--) {
    138         nex[i] = Last[a[i]];
    139         Last[a[i]] = i;
    140     }
    141     /// add edge
    142     
    143     int s = n * 3 + 2, t = s + 1, ss = s + 2, tt = s + 3;
    144     for(int i = 1; i <= n; i++) {
    145 //        add(i, i + n, [1, 1], 0);
    146         in[i + n]++; in[i]--;
    147         add(i + 2 * n, i, 1, val[i]);
    148         add(i + n, i + 1 + 2 * n, 1, 0);
    149         add(i + 2 * n, i + 1 + 2 * n, INF, 0); 
    150         if(nex[i]) {
    151             add(i + n, nex[i], 1, 0);
    152 //            printf("nex %d = %d  add(%d %d)
    ", i, nex[i], i + n, nex[i]);
    153         }
    154     }
    155     add(s, 1 + 2 * n, m, 0);
    156     add(n + 1 + 2 * n, t, m, 0);
    157     int Ck = tp;
    158     add(t, s, INF, 0);
    159     for(int i = 1; i <= t; i++) {
    160         if(in[i]) {
    161             if(in[i] > 0) {
    162                 add(ss, i, in[i], 0);
    163             }
    164             else  {
    165                 add(i, tt, -in[i], 0);
    166             }
    167         }
    168     }
    169     
    170     int cost1 = 0, cost2 = 0;
    171     solve(ss, tt, cost1);
    172     for(int i = Ck + 1; i <= tp; i++) {
    173         edge[i].c = 0;
    174     }
    175     solve(s, t, cost2);
    176     
    177     // get ways
    178     for(int i = 1; i <= m; i++) {
    179         Q.push(i);
    180     }
    181     for(int j = 1; j <= n; j++) {
    182         int x = j + 2 * n;
    183         for(int i = e[x]; i; i = edge[i].nex) {
    184             int y = edge[i].v;
    185             if(y == j && edge[i ^ 1].c) {
    186                 /// a num -> a[j]
    187                 tag[j] = Q.front();
    188                 Q.pop();
    189                 stk[++top] = Node(tag[j], a[j], 1);
    190                 break;
    191             }
    192         }
    193 //        printf("tag[j] = %d 
    ", tag[j]);
    194         stk[++top] = Node(tag[j], 0, 0);
    195         x = j + n;
    196         for(int i = e[x]; i; i = edge[i].nex) {
    197             int y = edge[i].v;
    198             if(y == nex[j] && edge[i ^ 1].c) {
    199                 tag[nex[j]] = tag[j];
    200                 break;
    201             }
    202             if(y == j + 1 + 2 * n && edge[i ^ 1].c) {
    203                 /// return queue
    204                 Q.push(tag[j]);
    205                 break;
    206             }
    207         }
    208     }
    209     
    210     printf("%d %d
    ", top, cost1 + cost2);
    211     for(int i = 1; i <= top; i++) stk[i].out();
    212     return 0;
    213 }
    AC代码
  • 相关阅读:
    HUAS 1482 lsy的后宫(DP+矩阵快速幂)
    HUAS 1483 mex(离线+线段树)
    oracle 分页
    oracle 表查询(二)
    oracle 表查询(一)
    oracle 表的管理
    oracle 用户管理
    oracle sql*plus常用命令
    挑选数据库
    oracle sequence用法
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10542679.html
Copyright © 2011-2022 走看看