• 洛谷 P4012 深海机器人问题【费用流】


    题目链接:https://www.luogu.org/problemnew/show/P4012

    洛谷 P4012 深海机器人问题

    输入输出样例

    输入样例#1:
    1 1
    2 2
    1 2
    3 4
    5 6
    7 2
    8 10
    9 3
    2 0 0
    2 2 2
    输出样例#1:
    42

    说明

    题解:建图方法如下:

      对于矩阵中的每个点,向东、向北分别与其相邻点都要连两条边(重边):

        1)容量为1,费用为该边价值的边;

        2)容量为INF,费用为0的边(因为多个深海机器人可以在同一时间占据同一位置)。

      对于每个起点:从S(源点)到这个点连:容量为该点机器人数,费用为0的边。

      对于每个终点:从这个点到T(汇点)连:容量为该点机器人数,费用为0的边。

    代码:

      1 #include<bits/stdc++.h>
      2 using namespace std;
      3 typedef long long ll;
      4 const int N = 455;
      5 const int M = N*4+30;
      6 const int INF = 0x3f3f3f3f;
      7 struct Edge { int to,next,cap,flow,cost; }edge[M];
      8 int head[N],tol;
      9 int pre[N],dis[N];
     10 bool vis[N];
     11 int V;      
     12 void init(int n) {
     13     V = n;
     14     tol = 0;
     15     memset(head,-1,sizeof(head));
     16 }
     17 void addedge(int u,int v,int cap,int cost) {
     18     edge[tol].to = v; edge[tol].cap = cap; edge[tol].cost = cost; edge[tol].flow = 0; edge[tol].next = head[u]; head[u] = tol++;
     19     edge[tol].to = u; edge[tol].cap = 0; edge[tol].cost = -cost; edge[tol].flow = 0; edge[tol].next = head[v]; head[v] = tol++;
     20 }
     21 bool spfa(int s,int t) {
     22     queue<int>q;
     23     for(int i = 0;i < V;i++) {
     24         dis[i] = INF;
     25         vis[i] = false;
     26         pre[i] = -1;
     27     }
     28     dis[s] = 0;
     29     vis[s] = true;
     30     q.push(s);
     31     while(!q.empty()) {
     32         int u = q.front();
     33         q.pop();
     34         vis[u] = false;
     35         for(int i = head[u]; i != -1;i = edge[i].next) {
     36             int v = edge[i].to;
     37             if(edge[i].cap > edge[i].flow && dis[v] > dis[u] + edge[i].cost ) {
     38                 dis[v] = dis[u] + edge[i].cost;
     39                 pre[v] = i;
     40                 if(!vis[v]) {
     41                     vis[v] = true;
     42                     q.push(v);
     43                 }
     44             }
     45         }
     46     }
     47     if(pre[t] == -1) return false;
     48     else return true;
     49 }
     50 int minCostMaxflow(int s,int t,int &cost) {
     51     int flow = 0;
     52     cost = 0;
     53     while(spfa(s,t)) {
     54         int Min = INF;
     55         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
     56             if(Min > edge[i].cap - edge[i].flow)
     57                 Min = edge[i].cap - edge[i].flow;
     58         }
     59         for(int i = pre[t];i != -1;i = pre[edge[i^1].to]) {
     60             edge[i].flow += Min;
     61             edge[i^1].flow -= Min;
     62             cost += edge[i].cost * Min;
     63         }
     64         flow += Min;
     65     }
     66     return flow;
     67 }
     68 int main() {
     69     int a, b, p, q, k, x, y, i, j, ans = 0;
     70     scanf("%d%d", &a, &b);//出发和目的地数目
     71     scanf("%d%d", &p, &q);
     72     init((p+1)*(q+1)+3);
     73 
     74     int s = (p+1)*(q+1)+1, t = (p+1)*(q+1)+2;
     75 
     76     for(i = 0; i <= p; ++i) {//p+1行,向东移动
     77         for(j = 0; j < q; ++j) {
     78             scanf("%d", &x);//边上的标本价值
     79             addedge(i*(q+1)+j, i*(q+1)+j+1, 1, -x);
     80             addedge(i*(q+1)+j, i*(q+1)+j+1, INF, 0);
     81         }
     82     }
     83     for(j = 0; j <= q; ++j) {//q+1列,向北移动
     84         for(i = 0; i < p; ++i) {
     85             scanf("%d", &x);
     86             addedge(i*(q+1)+j, i*(q+1)+j+q+1, 1, -x);
     87             addedge(i*(q+1)+j, i*(q+1)+j+q+1, INF, 0);
     88         }
     89     }
     90     for(i = 1; i <= a; ++i) {//起点
     91         scanf("%d%d%d", &k, &x, &y);
     92         addedge(s, x*(q+1)+y, k, 0);
     93     }
     94     for(i = 1; i <= b; ++i) {//终点
     95         scanf("%d%d%d", &k, &x, &y);
     96         addedge(x*(q+1)+y, t, k, 0);
     97     }
     98     minCostMaxflow(s, t, ans);
     99     printf("%d
    ", -ans);
    100     return 0;
    101 }
    View Code
  • 相关阅读:
    吴裕雄 python深度学习与实践(1)
    吴裕雄 python 机器学习-Logistic(1)
    吴裕雄 python 熵权法确定特征权重
    【Uva 1252】Twenty Questions
    【玲珑杯 round#18 B】图论你先敲完模板
    【Uva 10817】Headmaster's Headache
    【玲珑杯 round#18 A】计算几何你瞎暴力
    【Uva 12128】Perfect Service
    【UVa 12186】Another Crisis
    【Uva 10003】Cutting Sticks
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/9038586.html
Copyright © 2020-2023  润新知