• POJ 3422 最小费用最大流


    链接:

    http://poj.org/problem?id=3422

    题解:

    关键是如何处理“只能获取一次”的问题,为此可以为每个点创建伪点,由两条有向边相连。原始点到伪点连一条容量为1,权值为负分数的边;原始点到伪点连一条容量为无穷,权值为0的边。前者表示分数只能拿一次,后者表示第二次第三次……可以继续走这个点,但是不拿分数。负权是因为题目要求的是“最大费用”。又因为最多走同一个点K次,所以此处的无穷大取K就行了。

    代码:

      1 #include <map>
      2 #include <set>
      3 #include <cmath>
      4 #include <queue>
      5 #include <stack>
      6 #include <cstdio>
      7 #include <string>
      8 #include <vector>
      9 #include <cstdlib>
     10 #include <cstring>
     11 #include <sstream>
     12 #include <iostream>
     13 #include <algorithm>
     14 #include <functional>
     15 using namespace std;
     16 #define rep(i,a,n) for (int i=a;i<n;i++)
     17 #define per(i,a,n) for (int i=n-1;i>=a;i--)
     18 #define pb push_back
     19 #define mp make_pair
     20 #define all(x) (x).begin(),(x).end()
     21 #define SZ(x) ((int)(x).size())
     22 typedef vector<int> VI;
     23 typedef long long ll;
     24 typedef pair<int, int> PII;
     25 const ll mod = 1e9 + 7;
     26 const int inf = 0x3f3f3f3f;
     27 const double eps = 1e-10;
     28 const double pi = acos(-1.0);
     29 // head
     30 
     31 struct edge { int to, cap, cost, rev; };
     32 const int MAX_V = 2e4 + 7;
     33 int V;
     34 vector<edge> G[MAX_V];
     35 int h[MAX_V];
     36 int dist[MAX_V];
     37 int prevv[MAX_V], preve[MAX_V];
     38 
     39 void add_edge(int from, int to, int cap, int cost) {
     40     G[from].pb(edge{ to,cap,cost,(int)G[to].size() });
     41     G[to].pb(edge{ from,0,-cost,(int)G[from].size() - 1 });
     42 }
     43 
     44 int min_cost_flow(int s, int t, int f){
     45     int res = 0;
     46     memset(h, 0, sizeof(h));
     47     while (f > 0) {
     48         priority_queue<PII, vector<PII>, greater<PII> > que;
     49         memset(dist, 0x3f, sizeof(dist));
     50         dist[s] = 0;
     51         que.push(mp(s, 0));
     52         while (!que.empty()) {
     53             PII p = que.top(); que.pop();
     54             int v = p.second;
     55             rep(i, 0, G[v].size()) {
     56                 edge &e = G[v][i];
     57                 if (e.cap > 0 && dist[e.to] > dist[v] + e.cost + h[v] - h[e.to]) {
     58                     dist[e.to] = dist[v] + e.cost + h[v] - h[e.to];
     59                     prevv[e.to] = v;
     60                     preve[e.to] = i;
     61                     que.push(mp(dist[e.to], e.to));
     62                 }
     63             }
     64         }
     65         if (dist[t] == inf) return -1;
     66         rep(v, 0, V) h[v] += dist[v];
     67         int d = f;
     68         for (int v = t; v != s; v = prevv[v]) d = min(d, G[prevv[v]][preve[v]].cap);
     69         f -= d;
     70         res += d*h[t];
     71         for (int v = t; v != s; v = prevv[v]) {
     72             edge &e = G[prevv[v]][preve[v]];
     73             e.cap -= d;
     74             G[v][e.rev].cap += d;
     75         }
     76     }
     77     return res;
     78 }
     79 
     80 int n, k;
     81 
     82 int pos(int i, int j){
     83     return 2 * (i * n + j);
     84 }
     85 
     86 int main() {
     87     cin >> n >> k;
     88     V = n*n * 2;
     89     rep(i, 0, n) rep(j, 0, n) {
     90         int a;
     91         cin >> a;
     92         int cur = pos(i, j);
     93         add_edge(cur, cur + 1, 1, -a);
     94         add_edge(cur, cur + 1, inf, 0);
     95         if (i < n - 1) add_edge(cur + 1, pos(i + 1, j), inf, 0);
     96         if (j < n - 1) add_edge(cur + 1, pos(i, j + 1), inf, 0);
     97     }
     98     cout << - min_cost_flow(0, V - 1, k) << endl;
     99     return 0;
    100 }
  • 相关阅读:
    使用DragonFly进行智能镜像分发
    Operator部署Prometheus
    kubernetes中部署Jenkins并简单使用
    kubernetes常用控制器之DaemonSet
    kubernetes中部署nacos
    selenium自动化操作
    BeautifulSoup爬取网页分页
    细品BeautifulSoup节点访问
    再端一碗BeautifulSoup
    初试爬虫
  • 原文地址:https://www.cnblogs.com/baocong/p/6666198.html
Copyright © 2020-2023  润新知