zoukankan      html  css  js  c++  java
  • 洛谷 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
  • 相关阅读:
    【题解】【BT】【Leetcode】Populating Next Right Pointers in Each Node
    【题解】【BT】【Leetcode】Binary Tree Level Order Traversal
    【题解】【BST】【Leetcode】Unique Binary Search Trees
    【题解】【矩阵】【回溯】【Leetcode】Rotate Image
    【题解】【排列组合】【素数】【Leetcode】Unique Paths
    【题解】【矩阵】【回溯】【Leetcode】Unique Paths II
    【题解】【BST】【Leetcode】Validate Binary Search Tree
    【题解】【BST】【Leetcode】Convert Sorted Array to Binary Search Tree
    第 10 章 判断用户是否登录
    第 8 章 动态管理资源结合自定义登录页面
  • 原文地址:https://www.cnblogs.com/GraceSkyer/p/9038586.html
Copyright © 2011-2022 走看看