zoukankan      html  css  js  c++  java
  • [codeVS1917] 深海机器人问题(费用流,拆边)

    题目链接:http://codevs.cn/problem/1917/

    这题输入好恶心啊,看了半天看不懂。

    给一个地图,给出一些路径,这路径上的宝藏有价值。宝藏只能拿一次。

    再给出机器人起始位置,终点位置。终点位置不唯一且每一个终点只能允许有限个机器人到达,起点则不止一个机器人。

    问机器人收集到的最大价值。

    每一个点的宝藏只能拿一次,但是可以走无限次。那么可以建两条边,一条边的容量为1花费为-w,另一条则容量inf花费为0。这就保证只有一个会获得宝藏。

    关于机器人起点和终点:

    超级源链接所有机器人起点,流量为当前点机器人数,花费为0。同理终点连向超级汇。

    这题精髓之处就是在于如何确定每一个点保证仅拿一次了。

    上题拆点,这题拆边。有点意思。

      1 #include <bits/stdc++.h>
      2 using namespace std;
      3 
      4 typedef long long LL;
      5 typedef struct Node {
      6     int u, v, next;
      7     LL c, w;
      8 }Node;
      9 const int maxn = 6666;
     10 const int maxm = 66666;
     11 const LL mod = 0x3f3f3f3fLL;
     12 const LL inf = (1LL<<55);
     13 int tot, head[maxn];
     14 LL dist[maxn];
     15 LL cost, flow;
     16 Node e[maxm];
     17 int pre[maxn];
     18 bool visit[maxn];
     19 queue<int> Q;
     20 int S, T, N;
     21 
     22 void init() {
     23     S = T = N = 0;
     24     memset(head, -1, sizeof(head));
     25     tot = 0;
     26 }
     27 
     28 void adde(int u, int v, LL c, LL w) {
     29     e[tot].u = u; e[tot].v = v; e[tot].c = c; e[tot].w = w; e[tot].next = head[u]; head[u] = tot++;
     30     e[tot].u = v; e[tot].v = u; e[tot].c = 0; e[tot].w = -w; e[tot].next = head[v]; head[v] = tot++;
     31 }
     32 bool spfa(int s, int t, int n) {
     33     int i;
     34     for(i = 0; i <= n; i++) {
     35         dist[i] = inf;
     36         visit[i] = 0;
     37         pre[i] = -1;
     38     }
     39     while(!Q.empty()) Q.pop();
     40     Q.push(s);
     41     visit[s] = true;
     42     dist[s] = 0;
     43     pre[s] = -1;
     44     while(!Q.empty()) {
     45         int u = Q.front();
     46         visit[u] = false;
     47         Q.pop();
     48         for(int j = head[u]; j != -1; j = e[j].next) {
     49             if(e[j].c > 0 && dist[u] + e[j].w < dist[e[j].v]) {
     50                 dist[e[j].v] = dist[u] + e[j].w;
     51                 pre[e[j].v] = j;
     52                 if(!visit[e[j].v]) {
     53                     Q.push(e[j].v);
     54                     visit[e[j].v] = true;
     55                 }
     56             }
     57         }
     58     }
     59     if(dist[t] == inf) return false;
     60     else return true;
     61 }
     62 LL ChangeFlow(int t) {
     63     LL det = mod;
     64     int u = t;
     65     while(~pre[u]) {
     66         u = pre[u];
     67         det = min(det, e[u].c);
     68         u = e[u].u;
     69     }
     70     u = t;
     71     while(~pre[u]) {
     72         u = pre[u];
     73         e[u].c -= det;
     74         e[u ^ 1].c += det;
     75         u = e[u].u;
     76     }
     77     return det;
     78 }
     79 LL MinCostFlow(int s, int t, int n) {
     80     LL mincost, maxflow;
     81     mincost = maxflow = 0;
     82     while(spfa(s, t, n)) {
     83         LL det = ChangeFlow(t);
     84         mincost += det * dist[t];
     85         maxflow += det;
     86     }
     87     cost = mincost;
     88     flow = maxflow;
     89     return mincost;
     90 }
     91 
     92 int a, b, p, q;
     93 int k, x, y, w;
     94 
     95 int main() {
     96     init();
     97     scanf("%d%d%d%d",&a,&b,&p,&q);
     98     p++; q++;
     99     S = 0, T = p * q + 1, N = p * q + 2;
    100     for(int i = 0; i < p; i++) {
    101         for(int j = 1; j < q; j++) {
    102             scanf("%d", &w);
    103             adde(i*q+j, i*q+j+1, 1, -w);
    104             adde(i*q+j, i*q+j+1, inf, 0);
    105         }
    106     }
    107     for(int j = 1; j <= q; j++) {
    108         for(int i = 0; i < p - 1; i++) {
    109             scanf("%d", &w);
    110             adde(i*q+j, (i+1)*q+j, 1, -w);
    111             adde(i*q+j, (i+1)*q+j, inf, 0);
    112         }
    113     }
    114     for(int i = 0; i < a; i++) {
    115         scanf("%d%d%d",&k,&x,&y);
    116         adde(S, x*q+y+1, k, 0);
    117     }
    118     for(int i = 0; i < b; i++) {
    119         scanf("%d%d%d",&k,&x,&y);
    120         adde(x*q+y+1, T, k, 0);
    121     }
    122     printf("%lld
    ", -MinCostFlow(S, T, N));
    123     return 0;
    124 }
  • 相关阅读:
    HTTP 协议 简述
    Git 远程仓库相关
    Git 冲突问题
    单例模式
    extends Thread 与 implements Runnable 的区别
    正则表达式语法大全
    [Hadoop源码解读](六)MapReduce篇之MapTask类
    [Hadoop源码解读](五)MapReduce篇之Writable相关类
    [Hadoop源码解读](四)MapReduce篇之Counter相关类
    [Hadoop源码解读](三)MapReduce篇之Job类
  • 原文地址:https://www.cnblogs.com/kirai/p/6768820.html
Copyright © 2011-2022 走看看