zoukankan      html  css  js  c++  java
  • [HDOJ5855]Less Time, More profit(最大权闭合子图,二分,最大流)

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5855

    题意:有n个工厂m个商店,建造工厂需要花费pay和时间t,商店需要指定的几个工厂供货,如果同时供货的话可以获利pro。要求时间最小的情况下获利最多,求最小时间和最小时间下最大获利。

     岐爷博客学习了:http://www.cnblogs.com/wuyiqi/archive/2012/03/12/2391960.html

    这个图是这么建的。先读入数据后在区间(0~tmax)二分枚举时间time,代表当前建造时间不超过time的工厂可以同时建造。

    之后就是求最大权闭合图,最大权闭合图的的权 = 原图中权值为正的点的和(所有用户的收益之和) - 最小割(最大流)

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef struct Edge {
      5     int u, v, w, next;
      6 }Edge;
      7 
      8 const int inf = 0x7f7f7f7f;
      9 const int maxn = 2020;
     10 
     11 int cnt, dhead[maxn];
     12 int cur[maxn], dd[maxn];
     13 Edge dedge[20202020];
     14 int S, T, N;
     15 
     16 void init() {
     17     memset(dhead, -1, sizeof(dhead));
     18     for(int i = 0; i < maxn; i++) dedge[i].next = -1;
     19     S = 0; cnt = 0;
     20 }
     21 
     22 void adde(int u, int v, int w, int c1=0) {
     23     dedge[cnt].u = u; dedge[cnt].v = v; dedge[cnt].w = w; 
     24     dedge[cnt].next = dhead[u]; dhead[u] = cnt++;
     25     dedge[cnt].u = v; dedge[cnt].v = u; dedge[cnt].w = c1; 
     26     dedge[cnt].next = dhead[v]; dhead[v] = cnt++;
     27 }
     28 
     29 bool bfs(int s, int t, int n) {
     30     queue<int> q;
     31     for(int i = 0; i < n; i++) dd[i] = inf;
     32     dd[s] = 0;
     33     q.push(s);
     34     while(!q.empty()) {
     35         int u = q.front(); q.pop();
     36         for(int i = dhead[u]; ~i; i = dedge[i].next) {
     37             if(dd[dedge[i].v] > dd[u] + 1 && dedge[i].w > 0) {
     38                 dd[dedge[i].v] = dd[u] + 1;
     39                 if(dedge[i].v == t) return 1;
     40                 q.push(dedge[i].v);
     41             }
     42         }
     43     }
     44     return 0;
     45 }
     46 
     47 int dinic(int s, int t, int n) {
     48     int st[maxn], top;
     49     int u;
     50     int flow = 0;
     51     while(bfs(s, t, n)) {
     52         for(int i = 0; i < n; i++) cur[i] = dhead[i];
     53         u = s; top = 0;
     54         while(cur[s] != -1) {
     55             if(u == t) {
     56                 int tp = inf;
     57                 for(int i = top - 1; i >= 0; i--) {
     58                     tp = min(tp, dedge[st[i]].w);
     59                 }
     60                 flow += tp;
     61                 for(int i = top - 1; i >= 0; i--) {
     62                     dedge[st[i]].w -= tp;
     63                     dedge[st[i] ^ 1].w += tp;
     64                     if(dedge[st[i]].w == 0) top = i;
     65                 }
     66                 u = dedge[st[top]].u;
     67             }
     68             else if(cur[u] != -1 && dedge[cur[u]].w > 0 && dd[u] + 1 == dd[dedge[cur[u]].v]) {
     69                 st[top++] = cur[u];
     70                 u = dedge[cur[u]].v;
     71             }
     72             else {
     73                 while(u != s && cur[u] == -1) {
     74                     u = dedge[st[--top]].u;
     75                 }
     76                 cur[u] = dedge[cur[u]].next;
     77             }
     78         }
     79     }
     80     return flow;
     81 }
     82 
     83 inline bool scan_d(int &num) {
     84     char in;bool IsN=false;
     85     in=getchar();
     86     if(in==EOF) return false;
     87     while(in!='-'&&(in<'0'||in>'9')) in=getchar();
     88     if(in=='-'){ IsN=true;num=0;}
     89     else num=in-'0';
     90     while(in=getchar(),in>='0'&&in<='9'){
     91         num*=10,num+=in-'0';
     92     }
     93     if(IsN) num=-num;
     94     return true;
     95 }
     96 
     97 int n, m, L;
     98 int pay[maxn], t[maxn], pro[maxn];
     99 int k[maxn];
    100 int G[maxn][maxn];
    101 int maxx;
    102 
    103 int main() {
    104     // freopen("in", "r", stdin);
    105     int tt, _ = 1;
    106     scan_d(tt);
    107     while(tt--) {
    108         maxx = -1;
    109         memset(G, 0, sizeof(G));
    110         scan_d(n); scan_d(m); scan_d(L);
    111         for(int i = 1; i <= n; i++) {
    112             scan_d(pay[i]); scan_d(t[i]);
    113             maxx = max(maxx, t[i]);
    114         }
    115         for(int i = 1; i <= m; i++) {
    116             scan_d(pro[i]); scan_d(k[i]);
    117             for(int j = 0; j < k[i]; j++) {
    118                 scan_d(G[i][j]);
    119             }
    120         }
    121         int lo = 0, hi = maxx + 1;
    122         int ret1 = -1, ret2 = 0;
    123         while(lo <= hi) {
    124             init();
    125             S = 0, T = n + m + 1, N = T + 1;
    126             int mid = (lo + hi) >> 1;
    127             for(int i = 1; i <= n; i++) {
    128                 if(mid >= t[i]) adde(S, i, pay[i]);
    129                 else adde(S, i, inf);
    130             }
    131             int pos = 0;
    132             for(int i = 1; i <= m; i++) {
    133                 for(int j = 0; j < k[i]; j++) {
    134                     adde(G[i][j], i+n, inf);
    135                 }
    136                 adde(i+n, T, pro[i]);
    137                 pos += pro[i];
    138             }
    139             int flow = dinic(S, T, N);
    140             if(pos - flow >= L) {
    141                 hi = mid - 1;
    142                 ret1 = mid, ret2 = pos - flow;
    143             }
    144             else lo = mid + 1;
    145         }
    146         if(ret1 == -1) printf("Case #%d: impossible
    ", _++);
    147         else printf("Case #%d: %d %d
    ", _++, ret1, ret2);
    148     }
    149     return 0;
    150 }
  • 相关阅读:
    MTK android flash配置
    MTK平台缩写
    百度员工离职总结:如何做个好员工
    android 分区layout以及虚拟内存布局-小结
    Android eMMC Booting
    Android gingerbread eMMC booting
    Chrome插件开发
    jsonp解决CORS问题
    【好玩】将js代码转为日式表情
    多行文本溢出显示省略号(...)的方法
  • 原文地址:https://www.cnblogs.com/kirai/p/5807768.html
Copyright © 2011-2022 走看看