zoukankan      html  css  js  c++  java
  • bzoj 1391 [Ceoi2008]order

    Description

    有N个工作,M种机器,每种机器你可以租或者买过来. 每个工作包括若干道工序,每道工序需要某种机器来完成,你可以通过购买或租用机器来完成。 现在给出这些参数,求最大利润

    Input

    第一行给出 N,M(1<=N<=1200,1<=M<=1200) 下面将有N块数据,每块数据第一行给出完成这个任务能赚到的钱(其在[1,5000])及有多少道工序 接下来若干行每行两个数,分别描述完成工序所需要的机器编号及租用它的费用(其在[1,20000]) 最后M行,每行给出购买机器的费用(其在[1,20000])

    Output

    最大利润

    Sample Input

    2 3
    100 2
    1 30
    2 20
    100 2
    1 40
    3 80
    50
    80
    110

    Sample Output

    50

    HINT


      有点类似于最大权闭合子图。任务和源点连边,容量为获利,任务和完成它的工序所用机器连边,容量为租用费用,机器和汇点连边,容量为它的价格。答案是总获利 - 最大流。

      这些都还好。。最坑的是,我的模板在前几道题上正常运行,这道题用vectot炸掉了,一直鬼畜地Runtime Error,我也表示很绝望,换成数组才能Accepted。

    Code

      1 /**
      2  * bzoj
      3  * Problem#1391
      4  * Accepted
      5  * Time:4860ms
      6  * Memory:46372k
      7  */
      8 #include <iostream>
      9 #include <cstdio>
     10 #include <ctime>
     11 #include <cmath>
     12 #include <cctype>
     13 #include <cstring>
     14 #include <cstdlib>
     15 #include <fstream>
     16 #include <sstream>
     17 #include <algorithm>
     18 #include <map>
     19 #include <set>
     20 #include <stack>
     21 #include <queue>
     22 #include <vector>
     23 #include <stack>
     24 #ifndef WIN32
     25 #define Auto "%lld"
     26 #else
     27 #define Auto "%I64d"
     28 #endif
     29 using namespace std;
     30 typedef bool boolean;
     31 const signed int inf = (signed)((1u << 31) - 1);
     32 const int eps = 1e-6;
     33 #define smin(a, b) a = min(a, b)
     34 #define smax(a, b) a = max(a, b)
     35 #define max3(a, b, c) max(a, max(b, c))
     36 #define min3(a, b, c) min(a, min(b, c))
     37 template<typename T>
     38 inline boolean readInteger(T& u){
     39     char x;
     40     int aFlag = 1;
     41     while(!isdigit((x = getchar())) && x != '-' && x != -1);
     42     if(x == -1) {
     43         ungetc(x, stdin);    
     44         return false;
     45     }
     46     if(x == '-'){
     47         x = getchar();
     48         aFlag = -1;
     49     }
     50     for(u = x - '0'; isdigit((x = getchar())); u = (u << 1) + (u << 3) + x - '0');
     51     ungetc(x, stdin);
     52     u *= aFlag;
     53     return true;
     54 }
     55 
     56 typedef class Edge {
     57     public:
     58         int end;
     59         int next;
     60         int flow;
     61         int cap;
     62         Edge(int end = 0, int next = -1, int flow = 0, int cap = 0):end(end), next(next), flow(flow), cap(cap) {    }
     63 }Edge;
     64 
     65 typedef class MapManager {
     66     public:
     67         int ce;
     68         Edge* edge;
     69         int* h;
     70         
     71         MapManager():ce(0), h(NULL) {        }
     72         MapManager(int nodes, int limit):ce(0) {
     73             h = new int[(const int)(nodes + 1)];
     74             edge = new Edge[(const int)(limit + 1)];
     75             memset(h, -1, sizeof(int) * (nodes + 1));
     76         }
     77         
     78         inline void addEdge(int from, int end, int flow, int cap) {
     79             edge[ce] = (Edge(end, h[from], flow, cap));
     80             h[from] = ce++;
     81         }
     82         
     83         inline void addDoubleEdge(int from, int end, int cap) {
     84             addEdge(from, end, 0, cap);
     85             addEdge(end, from, cap, cap);
     86         }
     87         
     88         Edge& operator [] (int pos) {
     89             return edge[pos];
     90         }
     91 }MapManager;
     92 #define m_begin(g, i) (g).h[(i)]
     93 #define m_endpos -1
     94 
     95 int n, m;
     96 MapManager g;
     97 int s, t;
     98 int sum = 0;
     99 
    100 inline void init() {
    101     readInteger(n);
    102     readInteger(m);
    103     g = MapManager(n + m + 3, (n + 1) * (m + 1) * 2);
    104     s = 0, t = n + m + 1;
    105     for(int i = 1, a, b; i <= n; i++) {
    106         readInteger(a);
    107         readInteger(b);
    108         g.addDoubleEdge(s, i, a);
    109         sum += a;
    110         for(int j = 1, c, d; j <= b; j++) {
    111             readInteger(c);
    112             readInteger(d);
    113             g.addDoubleEdge(i, c + n, d);
    114         }
    115     }
    116     for(int i = 1, a; i <= m; i++) {
    117         readInteger(a);
    118         g.addDoubleEdge(i + n, t, a);
    119     }
    120 }
    121 
    122 int* dis;
    123 boolean* vis;
    124 queue<int> que;
    125 inline boolean bfs() {
    126     memset(vis, false, sizeof(boolean) * (t + 2));
    127     que.push(s);
    128     vis[s] = true;
    129     dis[s] = 0;
    130     while(!que.empty()) {
    131         int e = que.front();
    132         que.pop();
    133         for(int i = m_begin(g, e); i != m_endpos; i = g[i].next) {
    134             if(g[i].cap == g[i].flow)    continue;
    135             int eu = g[i].end;
    136             if(vis[eu])    continue;
    137             vis[eu] = true;
    138             dis[eu] = dis[e] + 1;
    139             que.push(eu);
    140         }
    141     }
    142     return vis[t];
    143 }
    144 
    145 int *cur;
    146 inline int blockedflow(int node, int minf) {
    147     if((node == t) || (minf == 0))    return minf;
    148     int f, flow = 0;
    149     for(int& i = cur[node]; i != m_endpos; i = g[i].next) {
    150         int& eu = g[i].end;
    151         if(dis[eu] == (dis[node] + 1) && (f = blockedflow(eu, min(minf, g[i].cap - g[i].flow))) > 0) {
    152             minf -= f;
    153             flow += f;
    154             g[i].flow += f;
    155             g[i ^ 1].flow -= f;
    156             if(minf == 0)    return flow;
    157         }
    158     }
    159     return flow;
    160 }
    161 
    162 inline void init_dinic() {
    163     vis = new boolean[(const int)(t + 3)];
    164     dis = new int[(const int)(t + 3)];
    165     cur = new int[(const int)(t + 3)];
    166 }
    167 
    168 inline int dinic() {
    169     int maxflow = 0;
    170     while(bfs()) {
    171         for(int i = s; i <= t; i++)
    172             cur[i] = m_begin(g, i);
    173         maxflow += blockedflow(s, inf);
    174     }
    175     return maxflow;
    176 } 
    177 
    178 inline void solve() {
    179     printf("%d
    ", sum - dinic());
    180 }
    181 
    182 int main() {
    183 //    freopen("order.in", "r", stdin);
    184     init();
    185     init_dinic();
    186     solve();
    187     return 0;
    188 }
  • 相关阅读:
    C标准中的一些预定义宏
    将智能设备连接到开发计算机上
    ATX电源短接哪两个引脚可以开机
    Visual C++ 编译器选项
    Visual C++ 链接器选项
    vs 2005 中的单元测试的生命周期
    .net study link
    C#的多线程机制探索(http://diy8.blog.sohu.com/741499.html)
    ![网页设计与编程] (小心眼花!)(http://www.fwcn.com/Bbs/viewthread.php?tid=10521)
    多个线程可能会试图同时访问某个对象。在多个线程同时争相访问某个对象的同时,如果一个线程修改了资源,有些线程可能会收到无效状态。例如,如果某个线程读取对象的字段,同时另一线程正在修改该字段,则第一个线程可能会收到无效的字段状态。这种情况称为竞用情况。
  • 原文地址:https://www.cnblogs.com/yyf0309/p/7136176.html
Copyright © 2011-2022 走看看