当前位置: 首页 > news >正文

topcoder srm 590 div1 (max_flow_template)

problem1 link

对于每一个,找到其在目标串中的位置,判断能不能移动即可。

problem2 link

如果最后的$limit$为$11=(1011)_{2}$,那么可以分别计算值为$(1011)_{2},(1010)_{2},(100x)_{2},(0xxx)_{2}$的答案数,$x$位置表示可以为任意。也就是可以忽略这些位。

当答案固定时,可以用高斯消元求解。

problem3 link

令$d(i,j)$表示点 $i$到点$j$的距离。

使用最小割求解。将每个点拆成$n$个点,第$i$个点拆成$p(i,0),p(i,1),...,p(i,n-1)$.其中$p(i,j)$如果与源点在一个割集,说明$d(0,i)\leq j$为假,与汇点在一个割集说明$d(0,i)\leq j$为真。

所以,如果一个割产生在边$p(i,j-1)\rightarrow p(i,j)$说明最后$d(0,i)=j$.其中边$p(i,j-1)\rightarrow p(i,j)$的代价为$(want[i]-j)^{2}$

有以下边:

(1)对于0点来说,$p(0,0)$与汇点的边流量为无穷大,说明,最后它与汇点在一个割集,所以$d(0,0)\leq 0$为真;

(2)对于$1\leq i < n$号点来说,源点到$p(i,0)$为无穷大(一定不可能),$p(i, n-1)$到汇点为无穷大(一定为真); $p(i,j-1)\rightarrow p(i,j),1\leq j < n)$为$(want[i]-j)^{2}$

(3)如果原来存在边$i\rightarrow j$,那么$p(i,k)\rightarrow p(j,k-1)$为无穷大,表示如果$d(0,i)>k$,那么一定有$d(0,j)>k-1$

 

code for problem1

#include <string>

class FoxAndChess {
 public:
  std::string ableToMove(const std::string &begin, const std::string &target) {
    int n = static_cast<int>(begin.size());
    int idx = 0;
    for (int i = 0; i < n; ++i) {
      if (begin[i] == 'L' || begin[i] == 'R') {
        while (idx < n && target[idx] == '.') {
          ++idx;
        }
        if (idx == n || begin[i] != target[idx] ||
            (begin[i] == 'L' && i < idx) || (begin[i] == 'R' && i > idx)) {
          return "Impossible";
        }
        ++idx;
      }
    }
    while (idx < n && target[idx] == '.') {
      ++idx;
    }
    if (idx != n) {
      return "Impossible";
    }
    return "Possible";
  }
};

code for problem2

#include <vector>

class XorCards {
 public:
  long long numberOfWays(const std::vector<long long> &number,
                         long long limit) {
    const int n = 52;
    const int m = static_cast<int>(number.size());
    long long result = 0;
    auto GetBit = [](long long t, int b) -> int {
      return (t & (1ll << b)) != 0 ? 1 : 0;
    };
    {
      std::vector<std::vector<int>> g(n, std::vector<int>(m + 1, 0));
      for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
          g[i][j] = GetBit(number[j], i);
        }
        g[i][m] = GetBit(limit, i);
      }
      result += Gauss(g);
    }
    for (int i = 0; i < n; ++i) {
      if (GetBit(limit, i) == 0) {
        continue;
      }
      std::vector<std::vector<int>> g(n, std::vector<int>(m + 1, 0));
      for (int j = i; j < n; ++j) {
        for (int k = 0; k < m; ++k) {
          g[j][k] = GetBit(number[k], j);
        }
        if (j > i) {
          g[j][m] = GetBit(limit, j);
        }
      }
      result += Gauss(g);
    }
    return result;
  }

 private:
  long long Gauss(std::vector<std::vector<int>> &g) {
    int n = static_cast<int>(g.size());
    int m = static_cast<int>(g[0].size()) - 1;
    int col = 0;

    auto HasBit = [&](int start, int col) {
      for (int i = n - 1; i >= start; --i) {
        if (g[i][col] != 0) return i;
      }
      return -1;
    };
    int row_number = 0;
    for (int i = 0; i < n && col < m; ++i) {
      int row = HasBit(i, col);
      while (row == -1 && col + 1 < m) {
        row = HasBit(i, ++col);
      }
      if (row == -1) {
        break;
      }
      if (row != i) {
        std::swap(g[i], g[row]);
      }
      for (int idx = 0; idx < n; ++idx) {
        if (idx != i && g[idx][col] != 0) {
          for (int k = 0; k <= m; ++k) {
            g[idx][k] ^= g[i][k];
          }
        }
      }
      ++col;
      ++row_number;
    }
    for (int i = row_number; i < n; ++i) {
      if (g[i][m] != 0) {
        return 0;
      }
    }
    if (m < row_number) {
      return 0;
    }
    return 1ll << (m - row_number);
  }
};

code for problem3

#include <limits>
#include <unordered_map>
#include <vector>

template <typename FlowType>
class MaxFlowSolver {
  static constexpr FlowType kMaxFlow = std::numeric_limits<FlowType>::max();
  static constexpr FlowType kZeroFlow = static_cast<FlowType>(0);
  struct node {
    int v;
    int next;
    FlowType cap;
  };

 public:
  int VertexNumber() const { return used_index_; }

  FlowType MaxFlow(int source, int sink) {
    source = GetIndex(source);
    sink = GetIndex(sink);

    int n = VertexNumber();
    std::vector<int> pre(n);
    std::vector<int> cur(n);
    std::vector<int> num(n);
    std::vector<int> h(n);
    for (int i = 0; i < n; ++i) {
      cur[i] = head_[i];
      num[i] = 0;
      h[i] = 0;
    }
    int u = source;
    FlowType result = 0;
    while (h[u] < n) {
      if (u == sink) {
        FlowType min_cap = kMaxFlow;
        int v = -1;
        for (int i = source; i != sink; i = edges_[cur[i]].v) {
          int k = cur[i];
          if (edges_[k].cap < min_cap) {
            min_cap = edges_[k].cap;
            v = i;
          }
        }
        result += min_cap;
        u = v;
        for (int i = source; i != sink; i = edges_[cur[i]].v) {
          int k = cur[i];
          edges_[k].cap -= min_cap;
          edges_[k ^ 1].cap += min_cap;
        }
      }
      int index = -1;
      for (int i = cur[u]; i != -1; i = edges_[i].next) {
        if (edges_[i].cap > 0 && h[u] == h[edges_[i].v] + 1) {
          index = i;
          break;
        }
      }
      if (index != -1) {
        cur[u] = index;
        pre[edges_[index].v] = u;
        u = edges_[index].v;
      } else {
        if (--num[h[u]] == 0) {
          break;
        }
        int k = n;
        cur[u] = head_[u];
        for (int i = head_[u]; i != -1; i = edges_[i].next) {
          if (edges_[i].cap > 0 && h[edges_[i].v] < k) {
            k = h[edges_[i].v];
          }
        }
        if (k + 1 < n) {
          num[k + 1] += 1;
        }
        h[u] = k + 1;
        if (u != source) {
          u = pre[u];
        }
      }
    }
    return result;
  }

  MaxFlowSolver() = default;

  void Clear() {
    edges_.clear();
    head_.clear();
    vertex_indexer_.clear();
    used_index_ = 0;
  }

  void InsertEdge(int from, int to, FlowType cap) {
    from = GetIndex(from);
    to = GetIndex(to);
    AddEdge(from, to, cap);
    AddEdge(to, from, kZeroFlow);
  }

 private:
  int GetIndex(int idx) {
    auto iter = vertex_indexer_.find(idx);
    if (iter != vertex_indexer_.end()) {
      return iter->second;
    }
    int map_idx = used_index_++;
    head_.push_back(-1);
    return vertex_indexer_[idx] = map_idx;
  }

  void AddEdge(int from, int to, FlowType cap) {
    node p;
    p.v = to;
    p.cap = cap;
    p.next = head_[from];
    head_[from] = static_cast<int>(edges_.size());
    edges_.emplace_back(p);
  }

  std::vector<node> edges_;
  std::vector<int> head_;

  std::unordered_map<int, int> vertex_indexer_;
  int used_index_ = 0;
};

#include <string>

class FoxAndCity {
 public:
  int minimalCost(const std::vector<std::string> linked,
                  const std::vector<int> want) {
    constexpr int kMaxCapacity = 1000000;
    int n = static_cast<int>(linked.size());
    MaxFlowSolver<int> solver;
    auto Index = [&](int u, int k) { return u * n + k; };
    int source = -1;
    int sink = -2;
    for (int i = 0; i < n; ++i) {
      if (i == 0) {
        solver.InsertEdge(Index(i, 0), sink, kMaxCapacity);
        continue;
      }

      solver.InsertEdge(source, Index(i, 0), kMaxCapacity);
      solver.InsertEdge(Index(i, n - 1), sink, kMaxCapacity);
      for (int j = 1; j < n; ++j) {
        solver.InsertEdge(Index(i, j - 1), Index(i, j),
                          (want[i] - j) * (want[i] - j));
      }
    }
    for (int i = 0; i < n; ++i) {
      for (int j = 0; j < n; ++j) {
        if (linked[i][j] == 'Y') {
          for (int k = 1; k < n; ++k) {
            solver.InsertEdge(Index(i, k), Index(j, k - 1), kMaxCapacity);
          }
        }
      }
    }
    return solver.MaxFlow(source, sink);
  }
};

转载于:https://www.cnblogs.com/jianglangcaijin/p/9384937.html

相关文章:

  • JavaScript 代码格式化
  • ubuntu12.04下面安装eclipse开发环境
  • Java虚拟机详解03----常用JVM配置参数
  • SQL基础
  • P1338 末日的传说 逆序数对
  • [jobdu]不用加减乘除做加法
  • 一枚前端UI组件库 KUI for Vue
  • Activity的启动模式与flag详解
  • 登录内网账号后,连接不上内网网址
  • c#中获取中文简拼
  • 【例题收藏】◇例题·III◇ 木と整数 / Integers on a Tree
  • window.location.hash属性介绍
  • Maven总结
  • perl常用正则表达式集合
  • Centos7安装搜狗输入法
  • 【RocksDB】TransactionDB源码分析
  • co.js - 让异步代码同步化
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • eclipse的离线汉化
  • IOS评论框不贴底(ios12新bug)
  • Python实现BT种子转化为磁力链接【实战】
  • Storybook 5.0正式发布:有史以来变化最大的版本\n
  • vue 个人积累(使用工具,组件)
  • 后端_MYSQL
  • 检测对象或数组
  • 精彩代码 vue.js
  • 如何使用Mybatis第三方插件--PageHelper实现分页操作
  • 如何优雅的使用vue+Dcloud(Hbuild)开发混合app
  • 网页视频流m3u8/ts视频下载
  • 吴恩达Deep Learning课程练习题参考答案——R语言版
  • 1.Ext JS 建立web开发工程
  • SAP CRM里Lead通过工作流自动创建Opportunity的原理讲解 ...
  • ​LeetCode解法汇总1276. 不浪费原料的汉堡制作方案
  • #etcd#安装时出错
  • #pragma data_seg 共享数据区(转)
  • (C语言)二分查找 超详细
  • (HAL)STM32F103C6T8——软件模拟I2C驱动0.96寸OLED屏幕
  • (附源码)计算机毕业设计ssm-Java网名推荐系统
  • (一)【Jmeter】JDK及Jmeter的安装部署及简单配置
  • ***汇编语言 实验16 编写包含多个功能子程序的中断例程
  • **PyTorch月学习计划 - 第一周;第6-7天: 自动梯度(Autograd)**
  • *Django中的Ajax 纯js的书写样式1
  • *ST京蓝入股力合节能 着力绿色智慧城市服务
  • .bat批处理(十一):替换字符串中包含百分号%的子串
  • .NET/C# 在 64 位进程中读取 32 位进程重定向后的注册表
  • .net打印*三角形
  • ??eclipse的安装配置问题!??
  • @angular/cli项目构建--Dynamic.Form
  • @KafkaListener注解详解(一)| 常用参数详解
  • [8481302]博弈论 斯坦福game theory stanford week 1
  • [Angular] 笔记 8:list/detail 页面以及@Input
  • [bzoj 3124][sdoi 2013 省选] 直径
  • [C#]OpenCvSharp结合yolov8-face实现L2CS-Net眼睛注视方向估计或者人脸朝向估计
  • [CCIE历程]CCIE # 20604
  • [CLR via C#]11. 事件