zoukankan      html  css  js  c++  java
  • HDU 3879 && BZOJ 1497:Base Station && 最大获利 (最大权闭合图)

    http://acm.hdu.edu.cn/showproblem.php?pid=3879

    http://www.lydsy.com/JudgeOnline/problem.php?id=1497

    题意:给出n个点m条边,其中每个点有一个权值代表修建这个点需要耗费的钱,然后m条边里面,代表如果两个修建好的点相连的话,那么可以得到一点利润。求最大的获利。

    思路:和BZOJ 1497是同一道题目。学习最大权闭合图的题目,看了一下不清楚应该怎么建图,然后只好搜一个论文来看看。http://wenku.baidu.com/view/6507a6fe2cc58bd63186bdaf.html

    建图:将S与n个点相连,权值为点权,将m条边当成点与T相连,权值为边权,边的两个顶点分别再和化成点的边相连,权值为INF。

    闭合图可以解决一些依赖关系,例如这道题目需要有两个顶点才可以得到一条边,边是依赖于两个顶点的形成的。

    于是网络是这样的:S->站的点->边的点->T。

    我们对这个网络得到的一个割 = 选择的站的花费 + 未选择的边的利润(也可以看作损失的利润),显然这个割集越小越好,即最小割。我们要求的是答案 = 选择的边的利润 - 选择的站的利润。

    那么我们一开始可以先累加得到一个选择所有边的利润tot,那么恰好tot - 最小割 = 选择所有边的利润 - 未选择边的利润 - 选择的站的花费 = 选择的边的利润 - 选择的站的利润 = 答案。

    所以跑一遍最大流后就用tot - 最大流就可以得到答案了。

    记得边的数组要开大一点。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <queue>
     5 using namespace std;
     6 #define INF 0x3f3f3f3f
     7 #define N 60010
     8 #define M 350010 // 30w不过
     9 struct Edge {
    10     int u, v, nxt, cap;
    11     Edge () {}
    12     Edge (int u, int v, int nxt, int cap) : u(u), v(v), nxt(nxt), cap(cap) {}
    13 } edge[M];
    14 int head[N], tot, S, T, cur[N], dis[N], gap[N], pre[N];
    15 
    16 void Add(int u, int v, int cap) {
    17     edge[tot] = Edge(u, v, head[u], cap); head[u] = tot++;
    18     edge[tot] = Edge(v, u, head[v], 0); head[v] = tot++;
    19 }
    20 
    21 void BFS() {
    22     queue<int> que;
    23     que.push(T);
    24     memset(dis, INF, sizeof(dis));
    25     memset(gap, 0, sizeof(gap));
    26     gap[0]++; dis[T] = 0;
    27     while(!que.empty()) {
    28         int u = que.front(); que.pop();
    29         for(int i = head[u]; ~i; i = edge[i].nxt) {
    30             if(dis[edge[i].v] != INF) continue;
    31             dis[edge[i].v] = dis[u] + 1;
    32             gap[dis[edge[i].v]]++;
    33             que.push(edge[i].v);
    34         }
    35     }
    36 }
    37 
    38 int ISAP(int n) {
    39     BFS();
    40     memcpy(cur, head, sizeof(cur));
    41     int u = pre[S] = S, flow, ans = 0, index, i;
    42     while(dis[S] < n) {
    43         if(u == T) {
    44             flow = INF;
    45             for(i = S; i != T; i = edge[cur[i]].v)
    46                 if(flow > edge[cur[i]].cap) flow = edge[cur[i]].cap, index = i;
    47             for(i = S; i != T; i = edge[cur[i]].v)
    48                 edge[cur[i]].cap -= flow, edge[cur[i]^1].cap += flow;
    49             u = index; ans += flow;
    50         }
    51         for(i = cur[u]; ~i; i = edge[i].nxt) if(edge[i].cap && dis[edge[i].v] + 1 == dis[u]) break;
    52         if(~i) { cur[u] = i; pre[edge[i].v] = u; u = edge[i].v; }
    53         else {
    54             if(--gap[dis[u]] == 0) break;
    55             int md = n + 1;
    56             for(i = head[u]; ~i; i = edge[i].nxt)
    57                 if(edge[i].cap && dis[edge[i].v] < md) md = dis[edge[i].v], cur[u] = i;
    58             gap[dis[u] = md + 1]++;
    59             u = pre[u];
    60         }
    61     }
    62     return ans;
    63 }
    64 
    65 int main() {
    66     int n, m;
    67     while(~scanf("%d%d", &n, &m)) {
    68         memset(head, -1, sizeof(head));
    69         tot = 0; S = 0; T = n + m + 1;
    70         for(int i = 1; i <= n; i++) {
    71             int w; scanf("%d", &w);
    72             Add(S, i, w); // 源点和站点相连
    73         }
    74         int tot = 0;
    75         for(int i = 1; i <= m; i++) {
    76             int a, b, c;
    77             scanf("%d%d%d",&a, &b, &c);
    78             tot += c; // 选择边的利润和
    79             Add(i + n, T, c); // 边的点和汇点相连
    80             Add(a, i + n, INF);
    81             Add(b, i + n, INF);
    82         }
    83         printf("%d
    ", tot - ISAP(T + 1));
    84     }
    85     return 0;
    86 }
  • 相关阅读:
    L1范式和L2范式的区别
    随机森林
    LDA-math-神奇的Gamma函数
    (转)共轭先验的理解
    Hits算法
    朴素贝叶斯分类算法(3)
    朴素贝叶斯分类算法(2)
    朴素贝叶斯分类算法(1)
    多项分布(multinominal distribution)
    从对偶问题到KKT条件
  • 原文地址:https://www.cnblogs.com/fightfordream/p/6354259.html
Copyright © 2011-2022 走看看